2026-03-04 15:41:21 +08:00
|
|
|
import { memo, RefObject, useRef, useState } from 'react';
|
2026-03-05 17:14:23 +08:00
|
|
|
import { setAccount, useAccount, usePlebbitRpcSettings } from '@bitsocialhq/bitsocial-react-hooks';
|
2024-06-22 10:32:19 +02:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2026-02-18 17:29:41 +08:00
|
|
|
import styles from './advanced-settings.module.css';
|
2024-06-18 11:50:17 +02:00
|
|
|
|
|
|
|
|
interface SettingsProps {
|
|
|
|
|
ipfsGatewayUrlsRef?: RefObject<HTMLTextAreaElement>;
|
|
|
|
|
mediaIpfsGatewayUrlRef?: RefObject<HTMLInputElement>;
|
|
|
|
|
pubsubProvidersRef?: RefObject<HTMLTextAreaElement>;
|
2026-01-02 16:48:21 +01:00
|
|
|
httpRoutersRef?: RefObject<HTMLTextAreaElement>;
|
2024-06-18 11:50:17 +02:00
|
|
|
ethRpcRef?: RefObject<HTMLTextAreaElement>;
|
|
|
|
|
solRpcRef?: RefObject<HTMLTextAreaElement>;
|
2026-01-02 15:53:02 +01:00
|
|
|
p2pRpcRef?: RefObject<HTMLInputElement>;
|
|
|
|
|
p2pDataPathRef?: RefObject<HTMLInputElement>;
|
2024-06-18 11:50:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const IPFSGatewaysSettings = ({ ipfsGatewayUrlsRef, mediaIpfsGatewayUrlRef }: SettingsProps) => {
|
|
|
|
|
const account = useAccount();
|
|
|
|
|
const { plebbitOptions, mediaIpfsGatewayUrl } = account || {};
|
|
|
|
|
const { ipfsGatewayUrls } = plebbitOptions || {};
|
|
|
|
|
const plebbitRpc = usePlebbitRpcSettings();
|
2025-05-24 22:05:16 +02:00
|
|
|
const isConnectedToRpc = plebbitRpc?.state === 'connected';
|
2024-06-18 11:50:17 +02:00
|
|
|
const ipfsGatewayUrlsDefaultValue = ipfsGatewayUrls?.join('\n');
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={styles.ipfsGatewaysSettings}>
|
|
|
|
|
<div className={styles.ipfsGatewaysSetting}>
|
|
|
|
|
<textarea
|
|
|
|
|
defaultValue={ipfsGatewayUrlsDefaultValue}
|
|
|
|
|
ref={ipfsGatewayUrlsRef}
|
|
|
|
|
disabled={isConnectedToRpc}
|
|
|
|
|
autoCorrect='off'
|
|
|
|
|
autoComplete='off'
|
|
|
|
|
spellCheck='false'
|
2026-01-02 15:43:01 +01:00
|
|
|
rows={ipfsGatewayUrls?.length || 1}
|
2024-06-18 11:50:17 +02:00
|
|
|
/>
|
|
|
|
|
</div>
|
2026-02-19 17:40:10 +08:00
|
|
|
<span className={styles.settingTip}>media IPFS gateway</span>
|
2024-06-18 11:50:17 +02:00
|
|
|
<div>
|
2025-05-22 17:48:00 +02:00
|
|
|
<input
|
|
|
|
|
type='text'
|
|
|
|
|
defaultValue={mediaIpfsGatewayUrl}
|
|
|
|
|
ref={mediaIpfsGatewayUrlRef}
|
|
|
|
|
disabled={isConnectedToRpc}
|
|
|
|
|
autoCorrect='off'
|
|
|
|
|
autoCapitalize='off'
|
|
|
|
|
spellCheck='false'
|
|
|
|
|
/>
|
2024-06-18 11:50:17 +02:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const PubsubProvidersSettings = ({ pubsubProvidersRef }: SettingsProps) => {
|
|
|
|
|
const account = useAccount();
|
|
|
|
|
const { plebbitOptions } = account || {};
|
|
|
|
|
const { pubsubHttpClientsOptions } = plebbitOptions || {};
|
|
|
|
|
const plebbitRpc = usePlebbitRpcSettings();
|
2025-05-24 22:05:16 +02:00
|
|
|
const isConnectedToRpc = plebbitRpc?.state === 'connected';
|
2024-06-18 11:50:17 +02:00
|
|
|
const pubsubProvidersDefaultValue = pubsubHttpClientsOptions?.join('\n');
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={styles.pubsubProvidersSettings}>
|
2025-05-22 17:48:00 +02:00
|
|
|
<textarea
|
|
|
|
|
defaultValue={pubsubProvidersDefaultValue}
|
|
|
|
|
ref={pubsubProvidersRef}
|
|
|
|
|
disabled={isConnectedToRpc}
|
|
|
|
|
autoCorrect='off'
|
|
|
|
|
autoCapitalize='off'
|
|
|
|
|
autoComplete='off'
|
|
|
|
|
spellCheck='false'
|
2026-01-02 15:43:01 +01:00
|
|
|
rows={pubsubHttpClientsOptions?.length || 1}
|
2025-05-22 17:48:00 +02:00
|
|
|
/>
|
2024-06-18 11:50:17 +02:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-02 16:48:21 +01:00
|
|
|
const HttpRoutersSettings = ({ httpRoutersRef }: SettingsProps) => {
|
|
|
|
|
const account = useAccount();
|
|
|
|
|
const { plebbitOptions } = account || {};
|
|
|
|
|
const { httpRoutersOptions } = plebbitOptions || {};
|
|
|
|
|
const plebbitRpc = usePlebbitRpcSettings();
|
|
|
|
|
const isConnectedToRpc = plebbitRpc?.state === 'connected';
|
|
|
|
|
const httpRoutersDefaultValue = httpRoutersOptions?.join('\n');
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={styles.httpRoutersSettings}>
|
|
|
|
|
<textarea
|
|
|
|
|
defaultValue={httpRoutersDefaultValue}
|
|
|
|
|
ref={httpRoutersRef}
|
|
|
|
|
disabled={isConnectedToRpc}
|
|
|
|
|
autoCorrect='off'
|
|
|
|
|
autoCapitalize='off'
|
|
|
|
|
autoComplete='off'
|
|
|
|
|
spellCheck='false'
|
|
|
|
|
rows={httpRoutersOptions?.length || 1}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-19 17:40:10 +08:00
|
|
|
const BlockchainProvidersSettings = ({ ethRpcRef, solRpcRef }: SettingsProps) => {
|
2024-06-18 11:50:17 +02:00
|
|
|
const account = useAccount();
|
|
|
|
|
const { plebbitOptions } = account || {};
|
|
|
|
|
const { chainProviders } = plebbitOptions || {};
|
|
|
|
|
const ethRpcDefaultValue = chainProviders?.['eth']?.urls.join('\n');
|
|
|
|
|
const solRpcDefaultValue = chainProviders?.['sol']?.urls.join('\n');
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={styles.blockchainProvidersSettings}>
|
2025-12-15 13:45:55 +01:00
|
|
|
<span className={styles.settingTip}>Ethereum RPC, for .eth domains</span>
|
2024-06-18 11:50:17 +02:00
|
|
|
<div>
|
2026-01-02 15:43:01 +01:00
|
|
|
<textarea
|
|
|
|
|
defaultValue={ethRpcDefaultValue}
|
|
|
|
|
ref={ethRpcRef}
|
|
|
|
|
autoCorrect='off'
|
|
|
|
|
autoComplete='off'
|
|
|
|
|
spellCheck='false'
|
|
|
|
|
rows={chainProviders?.['eth']?.urls?.length || 1}
|
|
|
|
|
/>
|
2024-06-18 11:50:17 +02:00
|
|
|
</div>
|
2025-12-15 13:45:55 +01:00
|
|
|
<span className={styles.settingTip}>Solana RPC, for .sol domains</span>
|
2024-06-18 11:50:17 +02:00
|
|
|
<div>
|
2026-01-02 15:43:01 +01:00
|
|
|
<textarea
|
|
|
|
|
defaultValue={solRpcDefaultValue}
|
|
|
|
|
ref={solRpcRef}
|
|
|
|
|
autoCorrect='off'
|
|
|
|
|
autoComplete='off'
|
|
|
|
|
spellCheck='false'
|
|
|
|
|
rows={chainProviders?.['sol']?.urls?.length || 1}
|
|
|
|
|
/>
|
2024-06-18 11:50:17 +02:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-02 15:53:02 +01:00
|
|
|
const P2pRPCSettings = ({ p2pRpcRef }: SettingsProps) => {
|
2024-06-18 11:50:17 +02:00
|
|
|
const [showInfo, setShowInfo] = useState(false);
|
|
|
|
|
const account = useAccount();
|
|
|
|
|
const { plebbitOptions } = account || {};
|
|
|
|
|
const { plebbitRpcClientsOptions } = plebbitOptions || {};
|
|
|
|
|
|
|
|
|
|
return (
|
2026-01-02 15:53:02 +01:00
|
|
|
<div className={styles.p2pRPCSettings}>
|
2024-06-18 11:50:17 +02:00
|
|
|
<div>
|
2026-01-02 15:53:02 +01:00
|
|
|
<input type='text' defaultValue={plebbitRpcClientsOptions} ref={p2pRpcRef} autoCorrect='off' autoCapitalize='off' spellCheck='false' />
|
2024-06-18 11:50:17 +02:00
|
|
|
<button onClick={() => setShowInfo(!showInfo)}>{showInfo ? 'X' : '?'}</button>
|
|
|
|
|
</div>
|
|
|
|
|
{showInfo && (
|
2026-01-02 15:53:02 +01:00
|
|
|
<div className={styles.p2pRpcSettingsInfo}>
|
|
|
|
|
use a P2P full node locally, or remotely with SSL
|
2024-06-18 11:50:17 +02:00
|
|
|
<br />
|
|
|
|
|
<ol>
|
|
|
|
|
<li>get secret auth key from the node</li>
|
|
|
|
|
<li>get IP address and port used by the node</li>
|
|
|
|
|
<li>
|
|
|
|
|
enter: <code>{`ws://<IP>:<port>/<secretAuthKey>`}</code>
|
|
|
|
|
</li>
|
|
|
|
|
<li>click save to connect</li>
|
|
|
|
|
</ol>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-02 15:53:02 +01:00
|
|
|
const P2pDataPathSettings = ({ p2pDataPathRef }: SettingsProps) => {
|
2024-06-18 11:50:17 +02:00
|
|
|
const plebbitRpc = usePlebbitRpcSettings();
|
|
|
|
|
const { plebbitRpcSettings } = plebbitRpc || {};
|
2025-05-24 22:05:16 +02:00
|
|
|
const isConnectedToRpc = plebbitRpc?.state === 'connected';
|
2025-05-22 17:48:00 +02:00
|
|
|
const path = plebbitRpcSettings?.plebbitOptions?.dataPath || '';
|
2024-06-18 11:50:17 +02:00
|
|
|
|
|
|
|
|
return (
|
2026-01-02 15:53:02 +01:00
|
|
|
<div className={styles.p2pDataPathSettings}>
|
2024-06-18 11:50:17 +02:00
|
|
|
<div>
|
2026-01-02 15:53:02 +01:00
|
|
|
<input autoCorrect='off' autoCapitalize='off' spellCheck='false' type='text' defaultValue={path} disabled={!isConnectedToRpc} ref={p2pDataPathRef} />
|
2024-06-18 11:50:17 +02:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-22 17:42:04 +02:00
|
|
|
const isElectron = window.electronApi?.isElectron === true;
|
2024-12-05 22:58:37 +01:00
|
|
|
|
2026-02-18 17:29:41 +08:00
|
|
|
const AdvancedSettings = () => {
|
2024-06-22 10:32:19 +02:00
|
|
|
const { t } = useTranslation();
|
2024-06-18 11:50:17 +02:00
|
|
|
const account = useAccount();
|
|
|
|
|
const { plebbitOptions } = account || {};
|
|
|
|
|
|
|
|
|
|
const ipfsGatewayUrlsRef = useRef<HTMLTextAreaElement>(null);
|
|
|
|
|
const mediaIpfsGatewayUrlRef = useRef<HTMLInputElement>(null);
|
|
|
|
|
const pubsubProvidersRef = useRef<HTMLTextAreaElement>(null);
|
|
|
|
|
const ethRpcRef = useRef<HTMLTextAreaElement>(null);
|
|
|
|
|
const solRpcRef = useRef<HTMLTextAreaElement>(null);
|
2024-12-05 23:02:18 +01:00
|
|
|
const httpRoutersRef = useRef<HTMLTextAreaElement>(null);
|
2026-01-02 15:53:02 +01:00
|
|
|
const p2pRpcRef = useRef<HTMLInputElement>(null);
|
|
|
|
|
const p2pDataPathRef = useRef<HTMLInputElement>(null);
|
2024-06-18 11:50:17 +02:00
|
|
|
|
|
|
|
|
const handleSave = async () => {
|
2024-12-05 23:02:18 +01:00
|
|
|
const ipfsGatewayUrls = ipfsGatewayUrlsRef.current?.value
|
|
|
|
|
.split('\n')
|
|
|
|
|
.map((url) => url.trim())
|
|
|
|
|
.filter((url) => url !== '');
|
|
|
|
|
|
2024-06-18 11:50:17 +02:00
|
|
|
const mediaIpfsGatewayUrl = mediaIpfsGatewayUrlRef.current?.value.trim();
|
2024-12-05 23:02:18 +01:00
|
|
|
|
|
|
|
|
const pubsubHttpClientsOptions = pubsubProvidersRef.current?.value
|
|
|
|
|
.split('\n')
|
|
|
|
|
.map((url) => url.trim())
|
|
|
|
|
.filter((url) => url !== '');
|
|
|
|
|
|
|
|
|
|
const ethRpcUrls = ethRpcRef.current?.value
|
|
|
|
|
.split('\n')
|
|
|
|
|
.map((url) => url.trim())
|
|
|
|
|
.filter((url) => url !== '');
|
|
|
|
|
|
|
|
|
|
const solRpcUrls = solRpcRef.current?.value
|
|
|
|
|
.split('\n')
|
|
|
|
|
.map((url) => url.trim())
|
|
|
|
|
.filter((url) => url !== '');
|
|
|
|
|
|
|
|
|
|
const httpRoutersOptions = httpRoutersRef.current?.value
|
|
|
|
|
.split('\n')
|
|
|
|
|
.map((url) => url.trim())
|
|
|
|
|
.filter((url) => url !== '');
|
|
|
|
|
|
2026-01-02 15:53:02 +01:00
|
|
|
const plebbitRpcClientsOptions = p2pRpcRef.current?.value.trim() ? [p2pRpcRef.current.value.trim()] : undefined;
|
|
|
|
|
const dataPath = p2pDataPathRef.current?.value.trim() || undefined;
|
2024-06-18 11:50:17 +02:00
|
|
|
|
2026-02-20 16:23:09 +08:00
|
|
|
const chainProviders: Record<string, { urls: string[] | undefined; chainId: number }> = {};
|
|
|
|
|
if (ethRpcUrls && ethRpcUrls.length > 0) {
|
|
|
|
|
chainProviders.eth = { urls: ethRpcUrls, chainId: 1 };
|
|
|
|
|
}
|
|
|
|
|
if (solRpcUrls && solRpcUrls.length > 0) {
|
|
|
|
|
chainProviders.sol = { urls: solRpcUrls, chainId: 101 };
|
|
|
|
|
}
|
2024-06-18 11:50:17 +02:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await setAccount({
|
|
|
|
|
...account,
|
|
|
|
|
mediaIpfsGatewayUrl,
|
|
|
|
|
plebbitOptions: {
|
|
|
|
|
...plebbitOptions,
|
|
|
|
|
ipfsGatewayUrls,
|
|
|
|
|
pubsubHttpClientsOptions,
|
|
|
|
|
chainProviders,
|
2024-12-05 23:02:18 +01:00
|
|
|
httpRoutersOptions,
|
2024-06-18 11:50:17 +02:00
|
|
|
plebbitRpcClientsOptions,
|
2024-12-05 23:02:18 +01:00
|
|
|
dataPath,
|
2024-06-18 11:50:17 +02:00
|
|
|
},
|
|
|
|
|
});
|
2024-12-05 23:02:18 +01:00
|
|
|
alert('Options saved, reloading...');
|
2024-07-12 20:22:09 +02:00
|
|
|
window.location.reload();
|
2024-06-18 11:50:17 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
if (e instanceof Error) {
|
|
|
|
|
alert('Error saving options: ' + e.message);
|
|
|
|
|
console.log(e);
|
|
|
|
|
} else {
|
|
|
|
|
alert('Error');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={styles.content}>
|
|
|
|
|
<button className={styles.saveOptions} onClick={handleSave}>
|
2024-06-22 10:32:19 +02:00
|
|
|
{t('save_options')}
|
2024-06-18 11:50:17 +02:00
|
|
|
</button>
|
|
|
|
|
<div className={styles.category}>
|
|
|
|
|
<span className={styles.categoryTitle}>IPFS gateways:</span>
|
|
|
|
|
<span className={styles.categorySettings}>
|
|
|
|
|
<IPFSGatewaysSettings ipfsGatewayUrlsRef={ipfsGatewayUrlsRef} mediaIpfsGatewayUrlRef={mediaIpfsGatewayUrlRef} />
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.category}>
|
|
|
|
|
<span className={styles.categoryTitle}>pubsub providers:</span>
|
|
|
|
|
<span className={styles.categorySettings}>
|
|
|
|
|
<PubsubProvidersSettings pubsubProvidersRef={pubsubProvidersRef} />
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
2026-01-02 16:48:21 +01:00
|
|
|
<div className={styles.category}>
|
|
|
|
|
<span className={styles.categoryTitle}>http routers:</span>
|
|
|
|
|
<span className={styles.categorySettings}>
|
|
|
|
|
<HttpRoutersSettings httpRoutersRef={httpRoutersRef} />
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
2024-06-18 11:50:17 +02:00
|
|
|
<div className={styles.category}>
|
2024-06-19 14:53:52 +02:00
|
|
|
<span className={styles.categoryTitle} style={{ marginBottom: '-5px' }}>
|
|
|
|
|
blockchain providers:
|
|
|
|
|
</span>
|
2024-06-18 11:50:17 +02:00
|
|
|
<span className={styles.categorySettings}>
|
2026-02-19 17:40:10 +08:00
|
|
|
<BlockchainProvidersSettings ethRpcRef={ethRpcRef} solRpcRef={solRpcRef} />
|
2024-06-18 11:50:17 +02:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.category}>
|
2025-12-30 18:21:04 +01:00
|
|
|
<span className={styles.categoryTitle}>Node RPC:</span>
|
2024-06-18 11:50:17 +02:00
|
|
|
<span className={styles.categorySettings}>
|
2026-01-02 15:53:02 +01:00
|
|
|
<P2pRPCSettings p2pRpcRef={p2pRpcRef} />
|
2024-06-18 11:50:17 +02:00
|
|
|
</span>
|
|
|
|
|
</div>
|
2024-12-05 22:58:37 +01:00
|
|
|
{isElectron && (
|
|
|
|
|
<div className={styles.category}>
|
2026-01-02 15:53:02 +01:00
|
|
|
<span className={styles.categoryTitle}>p2p data path:</span>
|
2024-12-05 22:58:37 +01:00
|
|
|
<span className={styles.categorySettings}>
|
2026-01-02 15:53:02 +01:00
|
|
|
<P2pDataPathSettings p2pDataPathRef={p2pDataPathRef} />
|
2024-12-05 22:58:37 +01:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2024-06-18 11:50:17 +02:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-04 15:41:21 +08:00
|
|
|
export default memo(AdvancedSettings);
|