Use the instance hook to fetch in SoapboxLoad, also store the data in Redux as a temporary workaround

This commit is contained in:
Alex Gleason 2024-10-11 04:26:27 -05:00
parent 0396cb1aef
commit 9d1ee47166
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
2 changed files with 31 additions and 15 deletions

View File

@ -1,22 +1,36 @@
import { useMemo } from 'react';
import { useEffect, useMemo } from 'react';
import { useInstanceV1 } from 'soapbox/api/hooks/instance/useInstanceV1';
import { useInstanceV2 } from 'soapbox/api/hooks/instance/useInstanceV2';
import { instanceV2Schema, upgradeInstance } from 'soapbox/schemas/instance';
import { useAppDispatch } from './useAppDispatch';
/** Get the Instance for the current backend. */
export function useInstance() {
const v2 = useInstanceV2();
const v1 = useInstanceV1({ enabled: v2.isError });
const upgradedV1 = useMemo(() => {
if (v1.instance) {
const instance = useMemo(() => {
if (v2.instance) {
return v2.instance;
} if (v1.instance) {
return upgradeInstance(v1.instance);
} else {
return instanceV2Schema.parse({});
}
}, [v1.instance]);
}, [v2.instance, v1.instance]);
const instance = v2.instance ?? upgradedV1 ?? instanceV2Schema.parse({});
const props = v2.isError ? v1 : v2;
// HACK: store the instance in Redux for legacy code
const dispatch = useAppDispatch();
useEffect(() => {
dispatch({
type: 'instanceV2/fetch/fulfilled',
payload: { instance },
});
}, [instance]);
return { ...props, instance };
}

View File

@ -1,7 +1,6 @@
import React, { useState, useEffect } from 'react';
import { IntlProvider } from 'react-intl';
import { fetchInstance } from 'soapbox/actions/instance';
import { fetchMe } from 'soapbox/actions/me';
import { loadSoapboxConfig } from 'soapbox/actions/soapbox';
import { useSignerStream } from 'soapbox/api/hooks/nostr/useSignerStream';
@ -12,17 +11,16 @@ import {
useAppDispatch,
useOwnAccount,
useLocale,
useInstance,
} from 'soapbox/hooks';
import MESSAGES from 'soapbox/messages';
/** Load initial data from the backend */
const loadInitial = () => {
// @ts-ignore
return async(dispatch, getState) => {
return async(dispatch) => {
// Await for authenticated fetch
await dispatch(fetchMe());
// Await for feature detection
await dispatch(fetchInstance());
// Await for configuration
await dispatch(loadSoapboxConfig());
};
@ -38,6 +36,7 @@ const SoapboxLoad: React.FC<ISoapboxLoad> = ({ children }) => {
const me = useAppSelector(state => state.me);
const { account } = useOwnAccount();
const instance = useInstance();
const swUpdating = useAppSelector(state => state.meta.swUpdating);
const { locale } = useLocale();
@ -54,6 +53,7 @@ const SoapboxLoad: React.FC<ISoapboxLoad> = ({ children }) => {
me && !account,
!isLoaded,
localeLoading,
instance.isLoading,
swUpdating,
hasNostr && me && (!isRelayOpen || !isSubscribed),
].some(Boolean);
@ -68,12 +68,14 @@ const SoapboxLoad: React.FC<ISoapboxLoad> = ({ children }) => {
// Load initial data from the API
useEffect(() => {
dispatch(loadInitial()).then(() => {
setIsLoaded(true);
}).catch(() => {
setIsLoaded(true);
});
}, []);
if (instance.isSuccess) {
dispatch(loadInitial()).then(() => {
setIsLoaded(true);
}).catch(() => {
setIsLoaded(true);
});
}
}, [instance.isSuccess]);
// intl is part of loading.
// It's important nothing in here depends on intl.