From 7fecd521d7b10268acef687f2ce364194edb7218 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 10 May 2022 18:48:57 -0500 Subject: [PATCH 1/3] Treat Pepe API as an extension, not a feature --- app/soapbox/containers/soapbox.tsx | 18 +++++++----------- app/soapbox/features/landing_page/index.tsx | 8 +++++--- .../public_layout/components/header.tsx | 12 +++++++----- .../components/modals/landing-page-modal.tsx | 12 +++++++----- app/soapbox/utils/__tests__/features-test.js | 18 ------------------ app/soapbox/utils/features.ts | 3 --- 6 files changed, 26 insertions(+), 45 deletions(-) diff --git a/app/soapbox/containers/soapbox.tsx b/app/soapbox/containers/soapbox.tsx index a3aa26a6a..76103ee7b 100644 --- a/app/soapbox/containers/soapbox.tsx +++ b/app/soapbox/containers/soapbox.tsx @@ -10,7 +10,7 @@ import { ScrollContext } from 'react-router-scroll-4'; import { loadInstance } from 'soapbox/actions/instance'; 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 * as BuildConfig from 'soapbox/build_config'; import Helmet from 'soapbox/components/helmet'; @@ -22,7 +22,6 @@ import WaitlistPage from 'soapbox/features/verification/waitlist_page'; import { createGlobals } from 'soapbox/globals'; import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures, useSoapboxConfig, useSettings } from 'soapbox/hooks'; import MESSAGES from 'soapbox/locales/messages'; -import { getFeatures } from 'soapbox/utils/features'; import { generateThemeCss } from 'soapbox/utils/theme'; import { checkOnboardingStatus } from '../actions/onboarding'; @@ -51,19 +50,16 @@ const loadInitial = () => { await dispatch(fetchMe()); // Await for feature detection await dispatch(loadInstance()); - - const promises = []; - - promises.push(dispatch(loadSoapboxConfig())); + // Await for configuration + await dispatch(loadSoapboxConfig()); 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) { - promises.push(dispatch(fetchVerificationConfig())); + if (pepeEnabled && !state.me) { + await dispatch(fetchVerificationConfig()); } - - await Promise.all(promises); }; }; diff --git a/app/soapbox/features/landing_page/index.tsx b/app/soapbox/features/landing_page/index.tsx index 4d408666d..4f53e32df 100644 --- a/app/soapbox/features/landing_page/index.tsx +++ b/app/soapbox/features/landing_page/index.tsx @@ -3,12 +3,14 @@ import { FormattedMessage } from 'react-intl'; import VerificationBadge from 'soapbox/components/verification_badge'; import RegistrationForm from 'soapbox/features/auth_login/components/registration_form'; -import { useAppSelector, useFeatures } from 'soapbox/hooks'; +import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks'; import { Button, Card, CardBody, Stack, Text } from '../../components/ui'; const LandingPage = () => { - const features = useFeatures(); + const soapboxConfig = useSoapboxConfig(); + const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true; + const instance = useAppSelector((state) => state.instance); const pepeOpen = useAppSelector(state => state.verification.getIn(['instance', 'registrations'], false) === true); @@ -56,7 +58,7 @@ const LandingPage = () => { // Render registration flow depending on features const renderBody = () => { - if (features.pepe && pepeOpen) { + if (pepeEnabled && pepeOpen) { return renderPepe(); } else if (instance.registrations) { return renderOpen(); diff --git a/app/soapbox/features/public_layout/components/header.tsx b/app/soapbox/features/public_layout/components/header.tsx index 79253194e..9ddb6eb31 100644 --- a/app/soapbox/features/public_layout/components/header.tsx +++ b/app/soapbox/features/public_layout/components/header.tsx @@ -5,7 +5,7 @@ import { Link, Redirect } from 'react-router-dom'; import { logIn, verifyCredentials } from 'soapbox/actions/auth'; import { fetchInstance } from 'soapbox/actions/instance'; -import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks'; +import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks'; import { openModal } from '../../../actions/modals'; import { Button, Form, HStack, IconButton, Input, Tooltip } from '../../../components/ui'; @@ -27,8 +27,10 @@ const Header = () => { const dispatch = useDispatch(); const intl = useIntl(); - const { logo } = useSoapboxConfig(); - const features = useFeatures(); + const soapboxConfig = useSoapboxConfig(); + const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true; + + const { logo } = soapboxConfig; const instance = useAppSelector((state) => state.instance); const isOpen = instance.get('registrations', false) === true; const pepeOpen = useAppSelector(state => state.verification.getIn(['instance', 'registrations'], false) === true); @@ -94,9 +96,9 @@ const Header = () => { {intl.formatMessage(messages.login)} - {(isOpen || features.pepe && pepeOpen) && ( + {(isOpen || pepeEnabled && pepeOpen) && ( - {(isOpen || features.pepe && pepeOpen) && ( - )} diff --git a/app/soapbox/utils/__tests__/features-test.js b/app/soapbox/utils/__tests__/features-test.js index 124e7e607..3ba9c90ba 100644 --- a/app/soapbox/utils/__tests__/features-test.js +++ b/app/soapbox/utils/__tests__/features-test.js @@ -148,22 +148,4 @@ describe('getFeatures', () => { 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); - }); - }); }); diff --git a/app/soapbox/utils/features.ts b/app/soapbox/utils/features.ts index 1086e946f..8407b673d 100644 --- a/app/soapbox/utils/features.ts +++ b/app/soapbox/utils/features.ts @@ -347,9 +347,6 @@ const getInstanceFeatures = (instance: Instance) => { */ paginatedContext: v.software === TRUTHSOCIAL, - /** Truth Social account registration API. */ - pepe: v.software === TRUTHSOCIAL, - /** * Can add polls to statuses. * @see POST /api/v1/statuses From 3785a2890f0a12772be8e3fc8ae18e21f299239f Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 10 May 2022 19:04:29 -0500 Subject: [PATCH 2/3] Registrations aren't really open unless accountCreation is supported --- app/soapbox/features/landing_page/index.tsx | 7 ++++--- app/soapbox/features/public_layout/components/header.tsx | 5 +++-- .../features/ui/components/modals/landing-page-modal.tsx | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/soapbox/features/landing_page/index.tsx b/app/soapbox/features/landing_page/index.tsx index 4f53e32df..a3e58c5b5 100644 --- a/app/soapbox/features/landing_page/index.tsx +++ b/app/soapbox/features/landing_page/index.tsx @@ -3,11 +3,12 @@ import { FormattedMessage } from 'react-intl'; import VerificationBadge from 'soapbox/components/verification_badge'; import RegistrationForm from 'soapbox/features/auth_login/components/registration_form'; -import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks'; +import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks'; import { Button, Card, CardBody, Stack, Text } from '../../components/ui'; const LandingPage = () => { + const features = useFeatures(); const soapboxConfig = useSoapboxConfig(); const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true; @@ -28,7 +29,7 @@ const LandingPage = () => { @@ -60,7 +61,7 @@ const LandingPage = () => { const renderBody = () => { if (pepeEnabled && pepeOpen) { return renderPepe(); - } else if (instance.registrations) { + } else if (features.accountCreation && instance.registrations) { return renderOpen(); } else { return renderClosed(); diff --git a/app/soapbox/features/public_layout/components/header.tsx b/app/soapbox/features/public_layout/components/header.tsx index 9ddb6eb31..39a98845a 100644 --- a/app/soapbox/features/public_layout/components/header.tsx +++ b/app/soapbox/features/public_layout/components/header.tsx @@ -5,7 +5,7 @@ import { Link, Redirect } from 'react-router-dom'; import { logIn, verifyCredentials } from 'soapbox/actions/auth'; import { fetchInstance } from 'soapbox/actions/instance'; -import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks'; +import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks'; import { openModal } from '../../../actions/modals'; import { Button, Form, HStack, IconButton, Input, Tooltip } from '../../../components/ui'; @@ -31,8 +31,9 @@ const Header = () => { const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true; const { logo } = soapboxConfig; + const features = useFeatures(); 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 [isLoading, setLoading] = React.useState(false); diff --git a/app/soapbox/features/ui/components/modals/landing-page-modal.tsx b/app/soapbox/features/ui/components/modals/landing-page-modal.tsx index 10d9f729f..583a1a144 100644 --- a/app/soapbox/features/ui/components/modals/landing-page-modal.tsx +++ b/app/soapbox/features/ui/components/modals/landing-page-modal.tsx @@ -4,7 +4,7 @@ import { defineMessages, useIntl } from 'react-intl'; import { Button } from 'soapbox/components/ui'; import { Modal } from 'soapbox/components/ui'; -import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks'; +import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks'; const messages = defineMessages({ download: { id: 'landing_page_modal.download', defaultMessage: 'Download' }, @@ -25,8 +25,9 @@ const LandingPageModal: React.FC = ({ onClose }) => { const { logo } = soapboxConfig; const instance = useAppSelector((state) => state.instance); + 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); return ( From 99b76bb7455ad5bfe4dd07ae20c7fcdf726e1bae Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 10 May 2022 19:11:26 -0500 Subject: [PATCH 3/3] Fix LandingPage test. Fix rememberSoapboxConfig not importing (!!) --- .../landing_page/__tests__/landing_page.test.tsx | 14 +++++++++----- app/soapbox/reducers/soapbox.js | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/soapbox/features/landing_page/__tests__/landing_page.test.tsx b/app/soapbox/features/landing_page/__tests__/landing_page.test.tsx index 0b6396d5b..02b9a4fe0 100644 --- a/app/soapbox/features/landing_page/__tests__/landing_page.test.tsx +++ b/app/soapbox/features/landing_page/__tests__/landing_page.test.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import LandingPage from '..'; import { rememberInstance } from '../../../actions/instance'; +import { SOAPBOX_CONFIG_REMEMBER_SUCCESS } from '../../../actions/soapbox'; import { PEPE_FETCH_INSTANCE_SUCCESS } from '../../../actions/verification'; import { render, screen, rootReducer, applyActions } from '../../../jest/test-helpers'; @@ -40,13 +41,16 @@ describe('', () => { 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, [{ - type: rememberInstance.fulfilled.type, - payload: { - version: '3.4.1 (compatible; TruthSocial 1.0.0)', - registrations: false, + type: SOAPBOX_CONFIG_REMEMBER_SUCCESS, + soapboxConfig: { + extensions: { + pepe: { + enabled: true, + }, + }, }, }, { type: PEPE_FETCH_INSTANCE_SUCCESS, diff --git a/app/soapbox/reducers/soapbox.js b/app/soapbox/reducers/soapbox.js index a208b4301..c8eeb7031 100644 --- a/app/soapbox/reducers/soapbox.js +++ b/app/soapbox/reducers/soapbox.js @@ -6,6 +6,7 @@ import { ConfigDB } from 'soapbox/utils/config_db'; import { ADMIN_CONFIG_UPDATE_SUCCESS } from '../actions/admin'; import { + SOAPBOX_CONFIG_REMEMBER_SUCCESS, SOAPBOX_CONFIG_REQUEST_SUCCESS, SOAPBOX_CONFIG_REQUEST_FAIL, } from '../actions/soapbox'; @@ -54,6 +55,8 @@ export default function soapbox(state = initialState, action) { switch(action.type) { case PLEROMA_PRELOAD_IMPORT: return preloadImport(state, action); + case SOAPBOX_CONFIG_REMEMBER_SUCCESS: + return fromJS(action.soapboxConfig); case SOAPBOX_CONFIG_REQUEST_SUCCESS: return importSoapboxConfig(state, fromJS(action.soapboxConfig), action.host); case SOAPBOX_CONFIG_REQUEST_FAIL: