Fix Bundle type errors, remove bundle error components, remove group slug support

This commit is contained in:
Alex Gleason 2023-10-07 16:00:42 -05:00
parent 0f10922c3d
commit 1b213452b7
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
10 changed files with 9 additions and 189 deletions

View File

@ -1,62 +0,0 @@
import React from 'react';
import { useGroupLookup } from 'soapbox/api/hooks';
import ColumnLoading from 'soapbox/features/ui/components/column-loading';
import { Layout } from '../ui';
interface IGroupLookup {
params: {
groupSlug: string;
};
}
interface IMaybeGroupLookup {
params?: {
groupSlug?: string;
groupId?: string;
};
}
function GroupLookupHoc(Component: React.ComponentType<{ params: { groupId: string } }>) {
const GroupLookup: React.FC<IGroupLookup> = (props) => {
const { entity: group } = useGroupLookup(props.params.groupSlug);
if (!group) return (
<>
<Layout.Main>
<ColumnLoading />
</Layout.Main>
<Layout.Aside />
</>
);
const newProps = {
...props,
params: {
...props.params,
id: group.id,
groupId: group.id,
},
};
return (
<Component {...newProps} />
);
};
const MaybeGroupLookup: React.FC<IMaybeGroupLookup> = (props) => {
const { params } = props;
if (params?.groupId) {
return <Component {...props} params={{ ...params, groupId: params.groupId }} />;
} else {
return <GroupLookup {...props} params={{ ...params, groupSlug: params?.groupSlug || '' }} />;
}
};
return MaybeGroupLookup;
}
export default GroupLookupHoc;

View File

@ -1,11 +0,0 @@
type HOC<P, R> = (Component: React.ComponentType<P>) => React.ComponentType<R>
type AsyncComponent<P> = () => Promise<{ default: React.ComponentType<P> }>
const withHoc = <P, R>(asyncComponent: AsyncComponent<P>, hoc: HOC<P, R>) => {
return async () => {
const { default: component } = await asyncComponent();
return { default: hoc(component) };
};
};
export default withHoc;

View File

@ -1,39 +0,0 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { Column, Stack, Text, IconButton } from 'soapbox/components/ui';
const messages = defineMessages({
title: { id: 'bundle_column_error.title', defaultMessage: 'Network error' },
body: { id: 'bundle_column_error.body', defaultMessage: 'Something went wrong while loading this page.' },
retry: { id: 'bundle_column_error.retry', defaultMessage: 'Try again' },
});
interface IBundleColumnError {
onRetry: () => void;
}
const BundleColumnError: React.FC<IBundleColumnError> = ({ onRetry }) => {
const intl = useIntl();
const handleRetry = () => {
onRetry();
};
return (
<Column label={intl.formatMessage(messages.title)}>
<Stack space={4} alignItems='center' justifyContent='center' className='min-h-[160px] rounded-lg p-10'>
<IconButton
iconClassName='h-10 w-10'
title={intl.formatMessage(messages.retry)}
src={require('@tabler/icons/refresh.svg')}
onClick={handleRetry}
/>
<Text align='center' theme='muted'>{intl.formatMessage(messages.body)}</Text>
</Stack>
</Column>
);
};
export default BundleColumnError;

View File

@ -1,35 +0,0 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { Modal } from 'soapbox/components/ui';
const messages = defineMessages({
error: { id: 'bundle_modal_error.message', defaultMessage: 'Something went wrong while loading this modal.' },
retry: { id: 'bundle_modal_error.retry', defaultMessage: 'Try again' },
close: { id: 'bundle_modal_error.close', defaultMessage: 'Close' },
});
interface IBundleModalError {
onRetry: () => void;
onClose: () => void;
}
const BundleModalError: React.FC<IBundleModalError> = ({ onRetry, onClose }) => {
const intl = useIntl();
const handleRetry = () => {
onRetry();
};
return (
<Modal
title={intl.formatMessage(messages.error)}
confirmationAction={onClose}
confirmationText={intl.formatMessage(messages.close)}
secondaryAction={handleRetry}
secondaryText={intl.formatMessage(messages.retry)}
/>
);
};
export default BundleModalError;

View File

@ -40,12 +40,10 @@ import {
import BundleContainer from '../containers/bundle-container';
import { BundleProps } from './bundle';
import BundleModalError from './bundle-modal-error';
import ModalLoading from './modal-loading';
/* eslint sort-keys: "error" */
const MODAL_COMPONENTS = {
const MODAL_COMPONENTS: Record<string, React.LazyExoticComponent<any>> = {
'ACCOUNT_MODERATION': AccountModerationModal,
'ACTIONS': ActionsModal,
'BIRTHDAYS': BirthdaysModal,
@ -108,10 +106,6 @@ export default class ModalRoot extends React.PureComponent<IModalRoot> {
return !['MEDIA', 'VIDEO', 'BOOST', 'CONFIRM', 'ACTIONS'].includes(modalId) ? <ModalLoading /> : null;
};
renderError: React.ComponentType<{ onRetry: (props?: BundleProps) => void }> = (props) => {
return <BundleModalError {...props} onClose={this.onClickClose} />;
};
onClickClose = (_?: ModalType) => {
const { onClose, type } = this.props;
onClose(type);
@ -124,7 +118,7 @@ export default class ModalRoot extends React.PureComponent<IModalRoot> {
return (
<Base onClose={this.onClickClose} type={type}>
{visible && (
<BundleContainer fetchComponent={MODAL_COMPONENTS[type]} loading={this.renderLoading(type)} error={this.renderError} renderDelay={200}>
<BundleContainer fetchComponent={MODAL_COMPONENTS[type]} loading={this.renderLoading(type)} renderDelay={200}>
{(SpecificComponent) => <SpecificComponent {...props} onClose={this.onClickClose} />}
</BundleContainer>
)}

View File

@ -15,8 +15,6 @@ import { fetchSuggestionsForTimeline } from 'soapbox/actions/suggestions';
import { expandHomeTimeline } from 'soapbox/actions/timelines';
import { useUserStream } from 'soapbox/api/hooks';
import { useSignerStream } from 'soapbox/api/hooks/nostr/useSignerStream';
import GroupLookupHoc from 'soapbox/components/hoc/group-lookup-hoc';
import withHoc from 'soapbox/components/hoc/with-hoc';
import SidebarNavigation from 'soapbox/components/sidebar-navigation';
import ThumbNavigation from 'soapbox/components/thumb-navigation';
import { Layout } from 'soapbox/components/ui';
@ -147,16 +145,6 @@ import { WrappedRoute } from './util/react-router-helpers';
// Without this it ends up in ~8 very commonly used bundles.
import 'soapbox/components/status';
const GroupTagsSlug = withHoc(GroupTags as any, GroupLookupHoc);
const GroupTagTimelineSlug = withHoc(GroupTagTimeline as any, GroupLookupHoc);
const GroupTimelineSlug = withHoc(GroupTimeline as any, GroupLookupHoc);
const GroupMembersSlug = withHoc(GroupMembers as any, GroupLookupHoc);
const GroupGallerySlug = withHoc(GroupGallery as any, GroupLookupHoc);
const ManageGroupSlug = withHoc(ManageGroup as any, GroupLookupHoc);
const EditGroupSlug = withHoc(EditGroup as any, GroupLookupHoc);
const GroupBlockedMembersSlug = withHoc(GroupBlockedMembers as any, GroupLookupHoc);
const GroupMembershipRequestsSlug = withHoc(GroupMembershipRequests as any, GroupLookupHoc);
interface ISwitchingColumnsArea {
children: React.ReactNode;
}
@ -310,18 +298,6 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) =>
{features.groups && <WrappedRoute path='/groups/:groupId/manage/requests' exact page={ManageGroupsPage} component={GroupMembershipRequests} content={children} />}
{features.groups && <WrappedRoute path='/groups/:groupId/posts/:statusId' exact page={StatusPage} component={Status} content={children} />}
{features.groupsTags && <WrappedRoute path='/group/:groupSlug/tags' exact page={GroupPage} component={GroupTagsSlug} content={children} />}
{features.groupsTags && <WrappedRoute path='/group/:groupSlug/tag/:tagId' exact page={GroupsPendingPage} component={GroupTagTimelineSlug} content={children} />}
{features.groups && <WrappedRoute path='/group/:groupSlug' publicRoute exact page={GroupPage} component={GroupTimelineSlug} content={children} />}
{features.groups && <WrappedRoute path='/group/:groupSlug/members' exact page={GroupPage} component={GroupMembersSlug} content={children} />}
{features.groups && <WrappedRoute path='/group/:groupSlug/media' publicRoute={!authenticatedProfile} component={GroupGallerySlug} page={GroupPage} content={children} />}
{features.groups && <WrappedRoute path='/group/:groupSlug/manage' exact page={ManageGroupsPage} component={ManageGroupSlug} content={children} />}
{features.groups && <WrappedRoute path='/group/:groupSlug/manage/edit' exact page={ManageGroupsPage} component={EditGroupSlug} content={children} />}
{features.groups && <WrappedRoute path='/group/:groupSlug/manage/blocks' exact page={ManageGroupsPage} component={GroupBlockedMembersSlug} content={children} />}
{features.groups && <WrappedRoute path='/group/:groupSlug/manage/requests' exact page={ManageGroupsPage} component={GroupMembershipRequestsSlug} content={children} />}
{features.groups && <WrappedRoute path='/group/:groupSlug/posts/:statusId' exact page={StatusPage} component={Status} content={children} />}
{features.groups && <Redirect from='/group/:groupSlug/statuses/:statusId' to='/group/:groupSlug/posts/:statusId' />}
<WrappedRoute path='/statuses/new' page={DefaultPage} component={NewStatus} content={children} exact />
<WrappedRoute path='/statuses/:statusId' exact page={StatusPage} component={Status} content={children} />
{features.scheduledStatuses && <WrappedRoute path='/scheduled_statuses' page={DefaultPage} component={ScheduledStatuses} content={children} />}

View File

@ -4,7 +4,6 @@ import { Redirect, Route, useHistory, RouteProps, RouteComponentProps, match as
import { Layout } from 'soapbox/components/ui';
import { useOwnAccount, useSettings } from 'soapbox/hooks';
import BundleColumnError from '../components/bundle-column-error';
import ColumnForbidden from '../components/column-forbidden';
import ColumnLoading from '../components/column-loading';
import ColumnsArea from '../components/columns-area';
@ -48,7 +47,7 @@ const WrappedRoute: React.FC<IWrappedRoute> = ({
const renderComponent = ({ match }: RouteComponentProps) => {
if (Page) {
return (
<BundleContainer fetchComponent={component} loading={renderLoading} error={renderError}>
<BundleContainer fetchComponent={component} loading={renderLoading}>
{Component =>
(
<Page params={match.params} layout={layout} {...componentParams}>
@ -63,7 +62,7 @@ const WrappedRoute: React.FC<IWrappedRoute> = ({
}
return (
<BundleContainer fetchComponent={component} loading={renderLoading} error={renderError}>
<BundleContainer fetchComponent={component} loading={renderLoading}>
{Component =>
(
<ColumnsArea layout={layout}>
@ -89,7 +88,6 @@ const WrappedRoute: React.FC<IWrappedRoute> = ({
const renderLoading = () => renderWithLayout(<ColumnLoading />);
const renderForbidden = () => renderWithLayout(<ColumnForbidden />);
const renderError = (props: any) => renderWithLayout(<BundleColumnError {...props} />);
const loginRedirect = () => {
const actualUrl = encodeURIComponent(`${history.location.pathname}${history.location.search}`);

View File

@ -31,7 +31,7 @@ const EventPage: React.FC<IEventPage> = ({ params, children }) => {
const history = useHistory();
const statusId = params?.statusId!;
const status = useAppSelector(state => getStatus(state, { id: statusId }));
const status = useAppSelector(state => getStatus(state, { id: statusId }) || undefined);
const event = status?.event;

View File

@ -3,7 +3,6 @@ import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useRouteMatch } from 'react-router-dom';
import { useGroup, useGroupMembershipRequests } from 'soapbox/api/hooks';
import GroupLookupHoc from 'soapbox/components/hoc/group-lookup-hoc';
import { Column, Icon, Layout, Stack, Text, Tabs } from 'soapbox/components/ui';
import GroupHeader from 'soapbox/features/group/components/group-header';
import LinkFooter from 'soapbox/features/ui/components/link-footer';
@ -191,4 +190,4 @@ const GroupPage: React.FC<IGroupPage> = ({ params, children }) => {
);
};
export default GroupLookupHoc(GroupPage as any) as any;
export default GroupPage;

View File

@ -13,15 +13,15 @@ import { federationRestrictionsDisclosed } from 'soapbox/utils/state';
import { Layout } from '../components/ui';
interface IRemoteInstancePage {
params: {
instance: string;
params?: {
instance?: string;
};
children: React.ReactNode;
}
/** Page for viewing a remote instance timeline. */
const RemoteInstancePage: React.FC<IRemoteInstancePage> = ({ children, params }) => {
const host = params.instance;
const host = params!.instance!;
const { account } = useOwnAccount();
const disclosed = useAppSelector(federationRestrictionsDisclosed);