Merge branch 'pepe-extension' into 'develop'

Treat Pepe API as an extension, not a feature

See merge request soapbox-pub/soapbox-fe!1348
This commit is contained in:
Alex Gleason 2022-05-11 17:37:50 +00:00
commit db91d4319b
8 changed files with 40 additions and 49 deletions

View File

@ -10,7 +10,7 @@ import { ScrollContext } from 'react-router-scroll-4';
import { loadInstance } from 'soapbox/actions/instance'; import { loadInstance } from 'soapbox/actions/instance';
import { fetchMe } from 'soapbox/actions/me'; import { fetchMe } from 'soapbox/actions/me';
import { loadSoapboxConfig } from 'soapbox/actions/soapbox'; import { loadSoapboxConfig, getSoapboxConfig } from 'soapbox/actions/soapbox';
import { fetchVerificationConfig } from 'soapbox/actions/verification'; import { fetchVerificationConfig } from 'soapbox/actions/verification';
import * as BuildConfig from 'soapbox/build_config'; import * as BuildConfig from 'soapbox/build_config';
import Helmet from 'soapbox/components/helmet'; import Helmet from 'soapbox/components/helmet';
@ -22,7 +22,6 @@ import WaitlistPage from 'soapbox/features/verification/waitlist_page';
import { createGlobals } from 'soapbox/globals'; import { createGlobals } from 'soapbox/globals';
import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures, useSoapboxConfig, useSettings } from 'soapbox/hooks'; import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures, useSoapboxConfig, useSettings } from 'soapbox/hooks';
import MESSAGES from 'soapbox/locales/messages'; import MESSAGES from 'soapbox/locales/messages';
import { getFeatures } from 'soapbox/utils/features';
import { generateThemeCss } from 'soapbox/utils/theme'; import { generateThemeCss } from 'soapbox/utils/theme';
import { checkOnboardingStatus } from '../actions/onboarding'; import { checkOnboardingStatus } from '../actions/onboarding';
@ -51,19 +50,16 @@ const loadInitial = () => {
await dispatch(fetchMe()); await dispatch(fetchMe());
// Await for feature detection // Await for feature detection
await dispatch(loadInstance()); await dispatch(loadInstance());
// Await for configuration
const promises = []; await dispatch(loadSoapboxConfig());
promises.push(dispatch(loadSoapboxConfig()));
const state = getState(); const state = getState();
const features = getFeatures(state.instance); const soapboxConfig = getSoapboxConfig(state);
const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true;
if (features.pepe && !state.me) { if (pepeEnabled && !state.me) {
promises.push(dispatch(fetchVerificationConfig())); await dispatch(fetchVerificationConfig());
} }
await Promise.all(promises);
}; };
}; };

View File

@ -2,6 +2,7 @@ import * as React from 'react';
import LandingPage from '..'; import LandingPage from '..';
import { rememberInstance } from '../../../actions/instance'; import { rememberInstance } from '../../../actions/instance';
import { SOAPBOX_CONFIG_REMEMBER_SUCCESS } from '../../../actions/soapbox';
import { PEPE_FETCH_INSTANCE_SUCCESS } from '../../../actions/verification'; import { PEPE_FETCH_INSTANCE_SUCCESS } from '../../../actions/verification';
import { render, screen, rootReducer, applyActions } from '../../../jest/test-helpers'; import { render, screen, rootReducer, applyActions } from '../../../jest/test-helpers';
@ -40,13 +41,16 @@ describe('<LandingPage />', () => {
expect(screen.queryByTestId('registrations-pepe')).not.toBeInTheDocument(); expect(screen.queryByTestId('registrations-pepe')).not.toBeInTheDocument();
}); });
it('renders Pepe flow for an open Truth Social instance', () => { it('renders Pepe flow if Pepe extension is enabled', () => {
const state = applyActions(undefined, [{ const state = applyActions(undefined, [{
type: rememberInstance.fulfilled.type, type: SOAPBOX_CONFIG_REMEMBER_SUCCESS,
payload: { soapboxConfig: {
version: '3.4.1 (compatible; TruthSocial 1.0.0)', extensions: {
registrations: false, pepe: {
enabled: true,
},
},
}, },
}, { }, {
type: PEPE_FETCH_INSTANCE_SUCCESS, type: PEPE_FETCH_INSTANCE_SUCCESS,

View File

@ -3,12 +3,15 @@ import { FormattedMessage } from 'react-intl';
import VerificationBadge from 'soapbox/components/verification_badge'; import VerificationBadge from 'soapbox/components/verification_badge';
import RegistrationForm from 'soapbox/features/auth_login/components/registration_form'; import RegistrationForm from 'soapbox/features/auth_login/components/registration_form';
import { useAppSelector, useFeatures } from 'soapbox/hooks'; import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks';
import { Button, Card, CardBody, Stack, Text } from '../../components/ui'; import { Button, Card, CardBody, Stack, Text } from '../../components/ui';
const LandingPage = () => { const LandingPage = () => {
const features = useFeatures(); const features = useFeatures();
const soapboxConfig = useSoapboxConfig();
const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true;
const instance = useAppSelector((state) => state.instance); const instance = useAppSelector((state) => state.instance);
const pepeOpen = useAppSelector(state => state.verification.getIn(['instance', 'registrations'], false) === true); const pepeOpen = useAppSelector(state => state.verification.getIn(['instance', 'registrations'], false) === true);
@ -26,7 +29,7 @@ const LandingPage = () => {
<FormattedMessage <FormattedMessage
id='registration.closed_message' id='registration.closed_message'
defaultMessage='{instance} is not accepting new members.' defaultMessage='{instance} is not accepting new members.'
values={{ instance: instance.get('title') }} values={{ instance: instance.title }}
/> />
</Text> </Text>
</Stack> </Stack>
@ -56,9 +59,9 @@ const LandingPage = () => {
// Render registration flow depending on features // Render registration flow depending on features
const renderBody = () => { const renderBody = () => {
if (features.pepe && pepeOpen) { if (pepeEnabled && pepeOpen) {
return renderPepe(); return renderPepe();
} else if (instance.registrations) { } else if (features.accountCreation && instance.registrations) {
return renderOpen(); return renderOpen();
} else { } else {
return renderClosed(); return renderClosed();

View File

@ -28,10 +28,13 @@ const Header = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const intl = useIntl(); const intl = useIntl();
const { logo, logoDarkMode } = useSoapboxConfig(); const soapboxConfig = useSoapboxConfig();
const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true;
const { logo, logoDarkMode } = soapboxConfig;
const features = useFeatures(); const features = useFeatures();
const instance = useAppSelector((state) => state.instance); const instance = useAppSelector((state) => state.instance);
const isOpen = instance.get('registrations', false) === true; const isOpen = features.accountCreation && instance.registrations;
const pepeOpen = useAppSelector(state => state.verification.getIn(['instance', 'registrations'], false) === true); const pepeOpen = useAppSelector(state => state.verification.getIn(['instance', 'registrations'], false) === true);
const [isLoading, setLoading] = React.useState(false); const [isLoading, setLoading] = React.useState(false);
@ -99,9 +102,9 @@ const Header = () => {
{intl.formatMessage(messages.login)} {intl.formatMessage(messages.login)}
</Button> </Button>
{(isOpen || features.pepe && pepeOpen) && ( {(isOpen || pepeEnabled && pepeOpen) && (
<Button <Button
to={features.pepe ? '/verify' : '/signup'} to={pepeEnabled ? '/verify' : '/signup'}
theme='primary' theme='primary'
> >
{intl.formatMessage(messages.register)} {intl.formatMessage(messages.register)}

View File

@ -20,11 +20,14 @@ interface ILandingPageModal {
const LandingPageModal: React.FC<ILandingPageModal> = ({ onClose }) => { const LandingPageModal: React.FC<ILandingPageModal> = ({ onClose }) => {
const intl = useIntl(); const intl = useIntl();
const { logo } = useSoapboxConfig(); const soapboxConfig = useSoapboxConfig();
const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true;
const { logo } = soapboxConfig;
const instance = useAppSelector((state) => state.instance); const instance = useAppSelector((state) => state.instance);
const features = useFeatures(); const features = useFeatures();
const isOpen = instance.get('registrations', false) === true; const isOpen = features.accountCreation && instance.registrations;
const pepeOpen = useAppSelector(state => state.verification.getIn(['instance', 'registrations'], false) === true); const pepeOpen = useAppSelector(state => state.verification.getIn(['instance', 'registrations'], false) === true);
return ( return (
@ -43,8 +46,8 @@ const LandingPageModal: React.FC<ILandingPageModal> = ({ onClose }) => {
{intl.formatMessage(messages.login)} {intl.formatMessage(messages.login)}
</Button> </Button>
{(isOpen || features.pepe && pepeOpen) && ( {(isOpen || pepeEnabled && pepeOpen) && (
<Button to={features.pepe ? '/verify' : '/signup'} theme='primary' block> <Button to={pepeEnabled ? '/verify' : '/signup'} theme='primary' block>
{intl.formatMessage(messages.register)} {intl.formatMessage(messages.register)}
</Button> </Button>
)} )}

View File

@ -6,6 +6,7 @@ import { ConfigDB } from 'soapbox/utils/config_db';
import { ADMIN_CONFIG_UPDATE_SUCCESS } from '../actions/admin'; import { ADMIN_CONFIG_UPDATE_SUCCESS } from '../actions/admin';
import { import {
SOAPBOX_CONFIG_REMEMBER_SUCCESS,
SOAPBOX_CONFIG_REQUEST_SUCCESS, SOAPBOX_CONFIG_REQUEST_SUCCESS,
SOAPBOX_CONFIG_REQUEST_FAIL, SOAPBOX_CONFIG_REQUEST_FAIL,
} from '../actions/soapbox'; } from '../actions/soapbox';
@ -54,6 +55,8 @@ export default function soapbox(state = initialState, action) {
switch(action.type) { switch(action.type) {
case PLEROMA_PRELOAD_IMPORT: case PLEROMA_PRELOAD_IMPORT:
return preloadImport(state, action); return preloadImport(state, action);
case SOAPBOX_CONFIG_REMEMBER_SUCCESS:
return fromJS(action.soapboxConfig);
case SOAPBOX_CONFIG_REQUEST_SUCCESS: case SOAPBOX_CONFIG_REQUEST_SUCCESS:
return importSoapboxConfig(state, fromJS(action.soapboxConfig), action.host); return importSoapboxConfig(state, fromJS(action.soapboxConfig), action.host);
case SOAPBOX_CONFIG_REQUEST_FAIL: case SOAPBOX_CONFIG_REQUEST_FAIL:

View File

@ -148,22 +148,4 @@ describe('getFeatures', () => {
expect(features.focalPoint).toBe(false); expect(features.focalPoint).toBe(false);
}); });
}); });
describe('pepe', () => {
it('is true for Truth Social', () => {
const instance = InstanceRecord({
version: '3.4.1 (compatible; TruthSocial 1.0.0)',
});
const features = getFeatures(instance);
expect(features.pepe).toBe(true);
});
it('is false for Pleroma', () => {
const instance = InstanceRecord({
version: '2.7.2 (compatible; Pleroma 2.3.0)',
});
const features = getFeatures(instance);
expect(features.pepe).toBe(false);
});
});
}); });

View File

@ -347,9 +347,6 @@ const getInstanceFeatures = (instance: Instance) => {
*/ */
paginatedContext: v.software === TRUTHSOCIAL, paginatedContext: v.software === TRUTHSOCIAL,
/** Truth Social account registration API. */
pepe: v.software === TRUTHSOCIAL,
/** /**
* Can add polls to statuses. * Can add polls to statuses.
* @see POST /api/v1/statuses * @see POST /api/v1/statuses