kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Load the instance and Nostr signer in a higher component
rodzic
9b92f30483
commit
2e82e3499d
|
@ -186,6 +186,7 @@
|
||||||
"vite-plugin-html": "^3.2.0",
|
"vite-plugin-html": "^3.2.0",
|
||||||
"vite-plugin-require": "^1.1.10",
|
"vite-plugin-require": "^1.1.10",
|
||||||
"vite-plugin-static-copy": "^1.0.0",
|
"vite-plugin-static-copy": "^1.0.0",
|
||||||
|
"websocket-ts": "^2.1.5",
|
||||||
"wicg-inert": "^3.1.1",
|
"wicg-inert": "^3.1.1",
|
||||||
"zod": "^3.23.5"
|
"zod": "^3.23.5"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { NostrEvent, NostrConnectResponse, NSchema as n } from '@nostrify/nostrify';
|
import { NostrEvent, NostrConnectResponse, NSchema as n } from '@nostrify/nostrify';
|
||||||
import { useEffect } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { WebsocketEvent } from 'websocket-ts';
|
||||||
|
|
||||||
import { useNostr } from 'soapbox/contexts/nostr-context';
|
import { useNostr } from 'soapbox/contexts/nostr-context';
|
||||||
import { nwcRequestSchema } from 'soapbox/schemas/nostr';
|
import { nwcRequestSchema } from 'soapbox/schemas/nostr';
|
||||||
|
@ -7,6 +8,9 @@ import { nwcRequestSchema } from 'soapbox/schemas/nostr';
|
||||||
function useSignerStream() {
|
function useSignerStream() {
|
||||||
const { relay, pubkey, signer } = useNostr();
|
const { relay, pubkey, signer } = useNostr();
|
||||||
|
|
||||||
|
const [opened, setOpened] = useState(false);
|
||||||
|
const [isConnected, setIsConnected] = useState(false);
|
||||||
|
|
||||||
async function sendConnect(response: NostrConnectResponse) {
|
async function sendConnect(response: NostrConnectResponse) {
|
||||||
if (!relay || !pubkey || !signer) return;
|
if (!relay || !pubkey || !signer) return;
|
||||||
|
|
||||||
|
@ -115,6 +119,29 @@ function useSignerStream() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (relay?.socket.readyState === WebSocket.OPEN) {
|
||||||
|
setOpened(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const openHandler = () => {
|
||||||
|
setOpened(true);
|
||||||
|
setIsConnected(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeHandler = () => {
|
||||||
|
setIsConnected(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
relay?.socket.addEventListener(WebsocketEvent.open, openHandler);
|
||||||
|
relay?.socket.addEventListener(WebsocketEvent.close, closeHandler);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
relay?.socket.removeEventListener(WebsocketEvent.open, openHandler);
|
||||||
|
relay?.socket.removeEventListener(WebsocketEvent.close, closeHandler);
|
||||||
|
};
|
||||||
|
}, [relay]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!relay || !pubkey) return;
|
if (!relay || !pubkey) return;
|
||||||
|
|
||||||
|
@ -132,6 +159,8 @@ function useSignerStream() {
|
||||||
};
|
};
|
||||||
|
|
||||||
}, [relay, pubkey, signer]);
|
}, [relay, pubkey, signer]);
|
||||||
|
|
||||||
|
return { opened, isConnected };
|
||||||
}
|
}
|
||||||
|
|
||||||
export { useSignerStream };
|
export { useSignerStream };
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { NRelay, NRelay1, NostrSigner } from '@nostrify/nostrify';
|
import { NRelay1, NostrSigner } from '@nostrify/nostrify';
|
||||||
import React, { createContext, useContext, useState, useEffect, useMemo } from 'react';
|
import React, { createContext, useContext, useState, useEffect, useMemo } from 'react';
|
||||||
|
|
||||||
import { NKeys } from 'soapbox/features/nostr/keys';
|
import { NKeys } from 'soapbox/features/nostr/keys';
|
||||||
|
@ -6,7 +6,7 @@ import { useOwnAccount } from 'soapbox/hooks';
|
||||||
import { useInstance } from 'soapbox/hooks/useInstance';
|
import { useInstance } from 'soapbox/hooks/useInstance';
|
||||||
|
|
||||||
interface NostrContextType {
|
interface NostrContextType {
|
||||||
relay?: NRelay;
|
relay?: NRelay1;
|
||||||
pubkey?: string;
|
pubkey?: string;
|
||||||
signer?: NostrSigner;
|
signer?: NostrSigner;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import { fetchScheduledStatuses } from 'soapbox/actions/scheduled-statuses';
|
||||||
import { fetchSuggestionsForTimeline } from 'soapbox/actions/suggestions';
|
import { fetchSuggestionsForTimeline } from 'soapbox/actions/suggestions';
|
||||||
import { expandHomeTimeline } from 'soapbox/actions/timelines';
|
import { expandHomeTimeline } from 'soapbox/actions/timelines';
|
||||||
import { useUserStream } from 'soapbox/api/hooks';
|
import { useUserStream } from 'soapbox/api/hooks';
|
||||||
import { useSignerStream } from 'soapbox/api/hooks/nostr/useSignerStream';
|
|
||||||
import SidebarNavigation from 'soapbox/components/sidebar-navigation';
|
import SidebarNavigation from 'soapbox/components/sidebar-navigation';
|
||||||
import ThumbNavigation from 'soapbox/components/thumb-navigation';
|
import ThumbNavigation from 'soapbox/components/thumb-navigation';
|
||||||
import { Layout } from 'soapbox/components/ui';
|
import { Layout } from 'soapbox/components/ui';
|
||||||
|
@ -462,7 +461,6 @@ const UI: React.FC<IUI> = ({ children }) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useUserStream();
|
useUserStream();
|
||||||
useSignerStream();
|
|
||||||
|
|
||||||
// The user has logged in
|
// The user has logged in
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { fetchInstance } from 'soapbox/actions/instance';
|
||||||
|
import { useSignerStream } from 'soapbox/api/hooks/nostr/useSignerStream';
|
||||||
|
import LoadingScreen from 'soapbox/components/loading-screen';
|
||||||
|
import { useAppDispatch, useFeatures } from 'soapbox/hooks';
|
||||||
|
|
||||||
|
interface ISoapboxInstance {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SoapboxInstance: React.FC<ISoapboxInstance> = ({ children }) => {
|
||||||
|
const features = useFeatures();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const [isLoaded, setIsLoaded] = useState(false);
|
||||||
|
const { opened } = useSignerStream();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch(fetchInstance()).then(() => {
|
||||||
|
setIsLoaded(true);
|
||||||
|
}).catch(() => {
|
||||||
|
setIsLoaded(true);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!isLoaded || (!opened && features.nostr)) {
|
||||||
|
return <LoadingScreen />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>{children}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SoapboxInstance;
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
|
|
||||||
import { fetchInstance } from 'soapbox/actions/instance';
|
|
||||||
import { fetchMe } from 'soapbox/actions/me';
|
import { fetchMe } from 'soapbox/actions/me';
|
||||||
import { loadSoapboxConfig } from 'soapbox/actions/soapbox';
|
import { loadSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||||
import LoadingScreen from 'soapbox/components/loading-screen';
|
import LoadingScreen from 'soapbox/components/loading-screen';
|
||||||
|
@ -17,7 +16,6 @@ import MESSAGES from 'soapbox/messages';
|
||||||
const loadInitial = () => {
|
const loadInitial = () => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return async(dispatch, getState) => {
|
return async(dispatch, getState) => {
|
||||||
await dispatch(fetchInstance());
|
|
||||||
await dispatch(fetchMe());
|
await dispatch(fetchMe());
|
||||||
await dispatch(loadSoapboxConfig());
|
await dispatch(loadSoapboxConfig());
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { preload } from '../actions/preload';
|
||||||
import { store } from '../store';
|
import { store } from '../store';
|
||||||
|
|
||||||
import SoapboxHead from './soapbox-head';
|
import SoapboxHead from './soapbox-head';
|
||||||
|
import SoapboxInstance from './soapbox-instance';
|
||||||
import SoapboxLoad from './soapbox-load';
|
import SoapboxLoad from './soapbox-load';
|
||||||
import SoapboxMount from './soapbox-mount';
|
import SoapboxMount from './soapbox-mount';
|
||||||
|
|
||||||
|
@ -31,11 +32,13 @@ const Soapbox: React.FC = () => {
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<StatProvider>
|
<StatProvider>
|
||||||
<NostrProvider>
|
<NostrProvider>
|
||||||
|
<SoapboxInstance>
|
||||||
<SoapboxHead>
|
<SoapboxHead>
|
||||||
<SoapboxLoad>
|
<SoapboxLoad>
|
||||||
<SoapboxMount />
|
<SoapboxMount />
|
||||||
</SoapboxLoad>
|
</SoapboxLoad>
|
||||||
</SoapboxHead>
|
</SoapboxHead>
|
||||||
|
</SoapboxInstance>
|
||||||
</NostrProvider>
|
</NostrProvider>
|
||||||
</StatProvider>
|
</StatProvider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
|
|
Ładowanie…
Reference in New Issue