mirror of
https://github.com/PrimalHQ/primal-web-app.git
synced 2024-09-28 16:00:50 +00:00
parent
c150c3d435
commit
5f7a7b5115
1
.env
1
.env
@ -1,4 +1,3 @@
|
||||
PRIMAL_PRIORITY_RELAYS = "wss://relay.primal.net"
|
||||
PRIMAL_CACHE_URL = "wss://cache2.primal.net/v1"
|
||||
PRIMAL_UPLOAD_URL = "wss://uploads.primal.net/v1"
|
||||
PRIMAL_CACHE_LIST_URL = "https://primal.net/.well-known/nostr-caches.json"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, onCleanup, onMount } from 'solid-js';
|
||||
import { AccountProvider } from './contexts/AccountContext';
|
||||
import { connectToDefault, disconnect } from './sockets';
|
||||
import { connect, disconnect } from './sockets';
|
||||
import { connect as uploadConnect, disconnect as uploadDisconnet } from './uploadSocket';
|
||||
import styles from './App.module.scss';
|
||||
import Toaster from './components/Toaster/Toaster';
|
||||
@ -22,7 +22,7 @@ export const APP_ID = `${Math.floor(Math.random()*10000000000)}`;
|
||||
const App: Component = () => {
|
||||
|
||||
onMount(() => {
|
||||
connectToDefault();
|
||||
connect();
|
||||
uploadConnect();
|
||||
});
|
||||
|
||||
|
@ -9,13 +9,9 @@ import {
|
||||
useContext
|
||||
} from "solid-js";
|
||||
import {
|
||||
cacheServer,
|
||||
cacheServerList,
|
||||
disconnect,
|
||||
isConnected,
|
||||
refreshSocketListeners,
|
||||
removeSocketListeners,
|
||||
setCacheServerList,
|
||||
socket,
|
||||
subscribeTo
|
||||
} from "../sockets";
|
||||
@ -51,7 +47,6 @@ export type SettingsContextStore = {
|
||||
defaultZapAmount: number,
|
||||
availableZapOptions: number[],
|
||||
notificationSettings: Record<string, boolean>,
|
||||
cachingServiceList: string[],
|
||||
applyContentModeration: boolean,
|
||||
contentModeration: ContentModeration[],
|
||||
actions: {
|
||||
@ -68,7 +63,6 @@ export type SettingsContextStore = {
|
||||
resetZapOptionsToDefault: (temp?: boolean) => void,
|
||||
updateNotificationSettings: (key: string, value: boolean, temp?: boolean) => void,
|
||||
restoreDefaultFeeds: () => void,
|
||||
saveCachingServiceList: () => void,
|
||||
setApplyContentModeration: (flag: boolean) => void,
|
||||
modifyContentModeration: (name: string, content?: boolean, trending?: boolean) => void,
|
||||
}
|
||||
@ -83,7 +77,6 @@ export const initialData = {
|
||||
defaultZapAmount: defaultZapAmount,
|
||||
availableZapOptions: defaultZapOptions,
|
||||
notificationSettings: { ...defaultNotificationSettings },
|
||||
cachingServiceList: [],
|
||||
applyContentModeration: true,
|
||||
contentModeration: [...defaultContentModeration],
|
||||
};
|
||||
@ -198,15 +191,6 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
!temp && saveSettings();
|
||||
};
|
||||
|
||||
const saveCachingServiceList = () => {
|
||||
updateStore('cachingServiceList', () => [...cacheServerList]);
|
||||
saveSettings(() => {
|
||||
if (!store.cachingServiceList.includes(cacheServer)) {
|
||||
disconnect();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const restoreDefaultFeeds = () => {
|
||||
|
||||
const subid = `restore_default_${APP_ID}`;
|
||||
@ -271,7 +255,6 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
defaultZapAmount: store.defaultZapAmount,
|
||||
zapOptions: store.availableZapOptions,
|
||||
notifications: store.notificationSettings,
|
||||
cachingServiceList: store.cachingServiceList,
|
||||
applyContentModeration: store.applyContentModeration,
|
||||
contentModeration: store.contentModeration,
|
||||
};
|
||||
@ -287,11 +270,7 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
}));
|
||||
}
|
||||
|
||||
if (type === 'EOSE') {
|
||||
then && then();
|
||||
unsub();
|
||||
}
|
||||
|
||||
unsub();
|
||||
return;
|
||||
});
|
||||
|
||||
@ -370,7 +349,6 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
defaultZapAmount,
|
||||
zapOptions,
|
||||
notifications,
|
||||
cachingServiceList,
|
||||
applyContentModeration,
|
||||
contentModeration,
|
||||
} = JSON.parse(content?.content);
|
||||
@ -387,12 +365,6 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
updateStore('notificationSettings', () => ({ ...defaultNotificationSettings}));
|
||||
}
|
||||
|
||||
if (cachingServiceList && Array.isArray(cachingServiceList) && cachingServiceList.length > 0) {
|
||||
updateStore('cachingServiceList', () => [ ...cachingServiceList ]);
|
||||
setCacheServerList(store.cachingServiceList);
|
||||
disconnect();
|
||||
}
|
||||
|
||||
updateStore('applyContentModeration', () => applyContentModeration);
|
||||
|
||||
if (Array.isArray(contentModeration) && contentModeration.length === 0) {
|
||||
@ -512,12 +484,6 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
html?.setAttribute('data-theme', store.theme);
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (store.cachingServiceList.length > 0) {
|
||||
setCacheServerList([...store.cachingServiceList]);
|
||||
}
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (isConnected()) {
|
||||
refreshSocketListeners(
|
||||
@ -553,7 +519,6 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
setZapOptions,
|
||||
resetZapOptionsToDefault,
|
||||
updateNotificationSettings,
|
||||
saveCachingServiceList,
|
||||
setApplyContentModeration,
|
||||
modifyContentModeration,
|
||||
},
|
||||
|
@ -15,7 +15,7 @@ import { Link } from '@solidjs/router';
|
||||
import { useAccountContext } from '../../contexts/AccountContext';
|
||||
import { getDefaultRelays } from '../../lib/relays';
|
||||
import { APP_ID } from '../../App';
|
||||
import { cacheServer, cacheServerList, connectToDefault, isConnected as isSocketConnected, setCacheServerList, socket, subscribeTo } from '../../sockets';
|
||||
import { isConnected as isSocketConnected, socket, subscribeTo } from '../../sockets';
|
||||
import { createStore } from 'solid-js/store';
|
||||
import Checkbox from '../../components/Checkbox/Checkbox';
|
||||
import ConfirmModal from '../../components/ConfirmModal/ConfirmModal';
|
||||
@ -28,12 +28,9 @@ const Network: Component = () => {
|
||||
|
||||
const intl = useIntl();
|
||||
const account = useAccountContext();
|
||||
const settings = useSettingsContext();
|
||||
|
||||
const [recomendedRelays, setRecomendedRelays] = createStore<Relay[]>([]);
|
||||
const [confirmRemoveRelay, setConfirmRemoveRelay] = createSignal('');
|
||||
const [confirmRemoveCacheService, setConfirmRemoveCacheService] = createSignal('');
|
||||
const [tryToRemoveLastCachingService, setTryToRemoveLastCachingService] = createSignal(false);
|
||||
const [invalidCustomRelay, setInvalidCustomRelay] = createSignal(false);
|
||||
const [invalidCachingService, setInvalidCachingService] = createSignal(false);
|
||||
|
||||
@ -74,15 +71,11 @@ const Network: Component = () => {
|
||||
return unusedRelays;
|
||||
}
|
||||
|
||||
const isRelayConnected = (url: string) => {
|
||||
const isConnected = (url: string) => {
|
||||
const relay: Relay | undefined = account?.relays.find(r => r.url === url);
|
||||
return relay && relay.status === WebSocket.OPEN;
|
||||
};
|
||||
|
||||
const isCachingServiceConnected = (url: string) => {
|
||||
return isSocketConnected() && cacheServer === url;
|
||||
};
|
||||
|
||||
const isPrimalRelayInUserSettings = () => {
|
||||
const rels: string[] = import.meta.env.PRIMAL_PRIORITY_RELAYS?.split(',') || [];
|
||||
|
||||
@ -142,38 +135,19 @@ const Network: Component = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const onRestoreCachingService = () => {
|
||||
connectToDefault();
|
||||
|
||||
setTimeout(() => {
|
||||
settings?.actions.saveCachingServiceList();
|
||||
}, 300);
|
||||
};
|
||||
|
||||
const onRemoveCacheService = (url: string) => {
|
||||
setCacheServerList(list => list.filter(cs => cs !== url));
|
||||
|
||||
settings?.actions.saveCachingServiceList();
|
||||
};
|
||||
|
||||
const onCachingServiceInput = () => {
|
||||
if (!cachingServiceInput || cachingServiceInput.value === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!cachingServiceInput || cachingServiceInput.value === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
const value = cachingServiceInput.value;
|
||||
|
||||
const url = new URL(value);
|
||||
|
||||
const url = new URL(cachingServiceInput.value);
|
||||
if (!url.origin.startsWith('wss://') && !url.origin.startsWith('ws://')) {
|
||||
throw(new Error('must be a wss'))
|
||||
}
|
||||
|
||||
setCacheServerList(list => [...list, value]);
|
||||
settings?.actions.saveCachingServiceList();
|
||||
cachingServiceInput.value = '';
|
||||
// account?.actions.changeCachingService(url.href);
|
||||
account?.actions.changeCachingService(url.href);
|
||||
setInvalidCachingService(false);
|
||||
} catch (e) {
|
||||
console.log('invalid url', e);
|
||||
@ -220,7 +194,7 @@ const Network: Component = () => {
|
||||
<button class={styles.relayItem} onClick={() => setConfirmRemoveRelay(relay.url)}>
|
||||
<div class={styles.relayEntry}>
|
||||
<Show
|
||||
when={isRelayConnected(relay.url)}
|
||||
when={isConnected(relay.url)}
|
||||
fallback={<div class={styles.disconnected}></div>}
|
||||
>
|
||||
<div class={styles.connected}></div>
|
||||
@ -230,14 +204,13 @@ const Network: Component = () => {
|
||||
{relay.url}
|
||||
</span>
|
||||
</div>
|
||||
<div class={styles.remove}>
|
||||
<div class={styles.closeIcon}></div> {intl.formatMessage(tActions.removeRelay)}
|
||||
</div>
|
||||
<div class={styles.remove}><div class={styles.closeIcon}></div> {intl.formatMessage(tActions.removeRelay)}</div>
|
||||
</button>
|
||||
)}
|
||||
</For>
|
||||
</Show>
|
||||
|
||||
|
||||
<Show when={!isPrimalRelayInUserSettings()}>
|
||||
<Checkbox
|
||||
id="primal_relay_check"
|
||||
@ -307,35 +280,21 @@ const Network: Component = () => {
|
||||
</HelpTip>
|
||||
</div>
|
||||
|
||||
<div class={styles.relayItem}>
|
||||
<div class={styles.relayEntry}>
|
||||
<Show
|
||||
when={isSocketConnected()}
|
||||
fallback={<div class={styles.disconnected}></div>}
|
||||
>
|
||||
<div class={styles.connected}></div>
|
||||
</Show>
|
||||
<div class={styles.webIcon}></div>
|
||||
<span>
|
||||
{socket()?.url}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<For each={cacheServerList}>
|
||||
{cs => (
|
||||
<button class={styles.relayItem} onClick={() => {
|
||||
if (cacheServerList.length === 1) {
|
||||
setTryToRemoveLastCachingService(true);
|
||||
return;
|
||||
}
|
||||
|
||||
setConfirmRemoveCacheService(cs)
|
||||
}}>
|
||||
<div class={styles.relayEntry}>
|
||||
<Show
|
||||
when={isCachingServiceConnected(cs)}
|
||||
fallback={<div class={styles.inactive}></div>}
|
||||
>
|
||||
<div class={styles.connected}></div>
|
||||
</Show>
|
||||
<div class={styles.webIcon}></div>
|
||||
<span class={styles.relayUrl} title={cs}>
|
||||
{cs}
|
||||
</span>
|
||||
</div>
|
||||
<div class={styles.remove}>
|
||||
<div class={styles.closeIcon}></div> {intl.formatMessage(tActions.removeRelay)}
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</For>
|
||||
|
||||
<div class={`${styles.settingsCaption} ${styles.secondCaption}`}>
|
||||
{intl.formatMessage(t.network.alternativeCachingService)}
|
||||
@ -366,7 +325,7 @@ const Network: Component = () => {
|
||||
|
||||
<button
|
||||
class={styles.restoreFeedsButton}
|
||||
onClick={onRestoreCachingService}
|
||||
onClick={() => account?.actions.changeCachingService()}
|
||||
>
|
||||
{intl.formatMessage(tActions.restoreCachingService)}
|
||||
</button>
|
||||
@ -385,42 +344,6 @@ const Network: Component = () => {
|
||||
}}
|
||||
onAbort={() => setConfirmRemoveRelay('')}
|
||||
/>
|
||||
|
||||
<ConfirmModal
|
||||
open={confirmRemoveCacheService().length > 0}
|
||||
description={intl.formatMessage(tActions.confirmRemoveCacheService, {
|
||||
url: confirmRemoveCacheService(),
|
||||
b: interpretBold,
|
||||
}) as string}
|
||||
onConfirm={() => {
|
||||
onRemoveCacheService(confirmRemoveCacheService())
|
||||
setConfirmRemoveCacheService('');
|
||||
}}
|
||||
onAbort={() => setConfirmRemoveCacheService('')}
|
||||
/>
|
||||
|
||||
<ConfirmModal
|
||||
open={confirmRemoveCacheService().length > 0}
|
||||
description={intl.formatMessage(tActions.confirmRemoveCacheService, {
|
||||
url: confirmRemoveCacheService(),
|
||||
b: interpretBold,
|
||||
}) as string}
|
||||
onConfirm={() => {
|
||||
onRemoveCacheService(confirmRemoveCacheService())
|
||||
setConfirmRemoveCacheService('');
|
||||
}}
|
||||
onAbort={() => setConfirmRemoveCacheService('')}
|
||||
/>
|
||||
|
||||
<ConfirmModal
|
||||
open={tryToRemoveLastCachingService()}
|
||||
description={intl.formatMessage(tPlaceholders.mustHaveOneCachingService)}
|
||||
title="Primal requires one caching service"
|
||||
confirmLabel="OK"
|
||||
onConfirm={() => {
|
||||
setTryToRemoveLastCachingService(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -306,13 +306,6 @@
|
||||
border-radius: 2px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.inactive {
|
||||
background-color: gray;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 2px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.relayUrl {
|
||||
max-width: 450px;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { createSignal } from "solid-js";
|
||||
import { createStore } from "solid-js/store";
|
||||
import { NostrEvent, NostrEOSE, NostrEventType, NostrEventContent } from "./types/primal";
|
||||
|
||||
export const [socket, setSocket] = createSignal<WebSocket>();
|
||||
@ -8,10 +7,6 @@ export const [isConnected, setConnected] = createSignal<Boolean>(false);
|
||||
|
||||
export const isNotConnected = () => !isConnected();
|
||||
|
||||
export let cacheServer = '';
|
||||
|
||||
export const [cacheServerList, setCacheServerList] = createStore<string[]>([]);
|
||||
|
||||
const onOpen = () => {
|
||||
setConnected(true);
|
||||
}
|
||||
@ -32,59 +27,21 @@ const onError = (error: Event) => {
|
||||
console.log("ws error: ", error);
|
||||
};
|
||||
|
||||
const getRandomCacheServer = (except?: string) => {
|
||||
const eligableList = except ?
|
||||
cacheServerList.filter(url => url !== except) :
|
||||
[...cacheServerList];
|
||||
|
||||
const index = eligableList.length < 2 ?
|
||||
0 :
|
||||
Math.round(Math.random() * (eligableList.length - 1));
|
||||
|
||||
return eligableList[index];
|
||||
}
|
||||
|
||||
export const cacheServerListPath = () => {
|
||||
return import.meta.env.PRIMAL_CACHE_LIST_URL;
|
||||
};
|
||||
|
||||
|
||||
export const connectToDefault = async () => {
|
||||
const url = cacheServerListPath();
|
||||
|
||||
if (url) {
|
||||
const response = await fetch(url);
|
||||
const list = await response.json();
|
||||
|
||||
setCacheServerList(() => [...list]);
|
||||
}
|
||||
|
||||
if (isConnected()) {
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
connect();
|
||||
}
|
||||
export let cacheServer = '';
|
||||
|
||||
export const connect = () => {
|
||||
if (isConnected()) {
|
||||
return;
|
||||
if (isNotConnected()) {
|
||||
cacheServer =
|
||||
localStorage.getItem('cacheServer') ||
|
||||
import.meta.env.PRIMAL_CACHE_URL;
|
||||
|
||||
setSocket(new WebSocket(cacheServer));
|
||||
console.log('CACHE SOCKET: ', socket());
|
||||
|
||||
socket()?.addEventListener('open', onOpen);
|
||||
socket()?.addEventListener('close', onClose);
|
||||
socket()?.addEventListener('error', onError);
|
||||
}
|
||||
|
||||
const selectedCacheServer = getRandomCacheServer(cacheServer);
|
||||
|
||||
cacheServer =
|
||||
localStorage.getItem('cacheServer') ||
|
||||
selectedCacheServer ||
|
||||
import.meta.env.PRIMAL_CACHE_URL;
|
||||
|
||||
setSocket(new WebSocket(cacheServer));
|
||||
console.log('CACHE SOCKET: ', socket());
|
||||
|
||||
socket()?.addEventListener('open', onOpen);
|
||||
socket()?.addEventListener('close', onClose);
|
||||
socket()?.addEventListener('error', onError);
|
||||
};
|
||||
|
||||
export const disconnect = () => {
|
||||
@ -93,7 +50,7 @@ export const disconnect = () => {
|
||||
|
||||
export const reset = () => {
|
||||
disconnect();
|
||||
setTimeout(connect, 200);
|
||||
setTimeout(connect, 1000);
|
||||
};
|
||||
|
||||
export const sendMessage = (message: string) => {
|
||||
|
@ -112,11 +112,6 @@ export const actions = {
|
||||
defaultMessage: 'Remove <b>{url}</b> from your relay list? This will disconnect you from the relay.',
|
||||
description: 'Label for remove relay confirmation',
|
||||
},
|
||||
confirmRemoveCacheService: {
|
||||
id: 'actions.confirmRemoveCacheService',
|
||||
defaultMessage: 'Remove <b>{url}</b> from your cache services list? This will disconnect you from this caching service, if connected.',
|
||||
description: 'Label for remove caching service confirmation',
|
||||
},
|
||||
restoreCachingService: {
|
||||
id: 'actions.restoreCachingService',
|
||||
defaultMessage: 'Restore default caching service',
|
||||
@ -1045,17 +1040,17 @@ export const settings = {
|
||||
},
|
||||
cachingService: {
|
||||
id: 'settings.network.cachingService',
|
||||
defaultMessage: 'Caching Services',
|
||||
defaultMessage: 'Caching Service',
|
||||
description: 'Title of the caching service section of the network settings sub-page',
|
||||
},
|
||||
connectedCachingService: {
|
||||
id: 'settings.network.connectedCachingService',
|
||||
defaultMessage: 'Caching service pool',
|
||||
defaultMessage: 'Connected caching service',
|
||||
description: 'Title of the caching service section of the network settings sub-page',
|
||||
},
|
||||
alternativeCachingService: {
|
||||
id: 'settings.network.alternativeCachingService',
|
||||
defaultMessage: 'Add a caching service url to the pool',
|
||||
defaultMessage: 'Connect to a different caching service',
|
||||
description: 'Title of the alternative caching service section of the Network settings sub-page',
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user