2023-03-23 12:20:19 -07:00
|
|
|
import React, { useMemo } from 'react';
|
2023-04-26 12:53:52 -07:00
|
|
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
2022-12-15 14:51:30 -08:00
|
|
|
import { useRouteMatch } from 'react-router-dom';
|
2022-12-12 14:36:56 -08:00
|
|
|
|
2023-05-01 11:58:40 -07:00
|
|
|
import { useGroup, useGroupMembershipRequests } from 'soapbox/api/hooks';
|
2023-04-17 12:28:20 -07:00
|
|
|
import GroupLookupHoc from 'soapbox/components/hoc/group-lookup-hoc';
|
2023-03-02 11:40:36 -08:00
|
|
|
import { Column, Icon, Layout, Stack, Text } from 'soapbox/components/ui';
|
2022-12-12 14:36:56 -08:00
|
|
|
import GroupHeader from 'soapbox/features/group/components/group-header';
|
|
|
|
import LinkFooter from 'soapbox/features/ui/components/link-footer';
|
|
|
|
import BundleContainer from 'soapbox/features/ui/containers/bundle-container';
|
|
|
|
import {
|
|
|
|
CtaBanner,
|
2022-12-18 04:17:45 -08:00
|
|
|
GroupMediaPanel,
|
|
|
|
SignUpPanel,
|
2023-03-21 14:34:15 -07:00
|
|
|
SuggestedGroupsPanel,
|
2022-12-12 14:36:56 -08:00
|
|
|
} from 'soapbox/features/ui/util/async-components';
|
2023-03-23 12:20:19 -07:00
|
|
|
import { useFeatures, useOwnAccount } from 'soapbox/hooks';
|
2022-12-12 14:36:56 -08:00
|
|
|
|
2022-12-15 14:51:30 -08:00
|
|
|
import { Tabs } from '../components/ui';
|
|
|
|
|
2023-05-01 11:58:40 -07:00
|
|
|
import type { Group } from 'soapbox/schemas';
|
|
|
|
|
2022-12-16 15:33:07 -08:00
|
|
|
const messages = defineMessages({
|
|
|
|
all: { id: 'group.tabs.all', defaultMessage: 'All' },
|
|
|
|
members: { id: 'group.tabs.members', defaultMessage: 'Members' },
|
2023-04-10 13:22:08 -07:00
|
|
|
media: { id: 'group.tabs.media', defaultMessage: 'Media' },
|
2023-03-23 12:20:19 -07:00
|
|
|
tags: { id: 'group.tabs.tags', defaultMessage: 'Topics' },
|
2022-12-16 15:33:07 -08:00
|
|
|
});
|
|
|
|
|
2022-12-12 14:36:56 -08:00
|
|
|
interface IGroupPage {
|
|
|
|
params?: {
|
2023-04-17 12:28:20 -07:00
|
|
|
groupId?: string
|
2023-01-27 14:04:42 -08:00
|
|
|
}
|
|
|
|
children: React.ReactNode
|
2022-12-12 14:36:56 -08:00
|
|
|
}
|
|
|
|
|
2023-04-26 12:53:52 -07:00
|
|
|
const DeletedBlankslate = () => (
|
|
|
|
<Stack space={4} className='py-10' alignItems='center'>
|
|
|
|
<div className='rounded-full bg-danger-200 p-3 dark:bg-danger-400/20'>
|
|
|
|
<Icon
|
|
|
|
src={require('@tabler/icons/trash.svg')}
|
|
|
|
className='h-6 w-6 text-danger-600 dark:text-danger-400'
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<Text theme='muted'>
|
|
|
|
<FormattedMessage
|
|
|
|
id='group.deleted.message'
|
|
|
|
defaultMessage='This group has been deleted.'
|
|
|
|
/>
|
|
|
|
</Text>
|
|
|
|
</Stack>
|
|
|
|
);
|
|
|
|
|
2023-03-15 11:53:17 -07:00
|
|
|
const PrivacyBlankslate = () => (
|
|
|
|
<Stack space={4} className='py-10' alignItems='center'>
|
2023-04-26 12:53:52 -07:00
|
|
|
<div className='rounded-full bg-gray-200 p-3 dark:bg-gray-800'>
|
|
|
|
<Icon
|
|
|
|
src={require('@tabler/icons/eye-off.svg')}
|
|
|
|
className='h-6 w-6 text-gray-600 dark:text-gray-600'
|
|
|
|
/>
|
2023-03-15 11:53:17 -07:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<Text theme='muted'>
|
2023-04-26 12:53:52 -07:00
|
|
|
<FormattedMessage
|
|
|
|
id='group.private.message'
|
|
|
|
defaultMessage='Content is only visible to group members'
|
|
|
|
/>
|
2023-03-15 11:53:17 -07:00
|
|
|
</Text>
|
|
|
|
</Stack>
|
|
|
|
);
|
|
|
|
|
|
|
|
const BlockedBlankslate = ({ group }: { group: Group }) => (
|
|
|
|
<Stack space={4} className='py-10' alignItems='center'>
|
2023-04-26 12:53:52 -07:00
|
|
|
<div className='rounded-full bg-danger-200 p-3 dark:bg-danger-400/20'>
|
|
|
|
<Icon
|
|
|
|
src={require('@tabler/icons/ban.svg')}
|
|
|
|
className='h-6 w-6 text-danger-600 dark:text-danger-400'
|
|
|
|
/>
|
2023-03-15 11:53:17 -07:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<Text theme='muted'>
|
2023-04-26 12:53:52 -07:00
|
|
|
<FormattedMessage
|
|
|
|
id='group.banned.message'
|
2023-06-03 11:31:21 -07:00
|
|
|
defaultMessage='You are banned from {group}'
|
|
|
|
values={{
|
|
|
|
group: <Text theme='inherit' tag='span' dangerouslySetInnerHTML={{ __html: group.display_name_html }} />,
|
|
|
|
}}
|
2023-04-26 12:53:52 -07:00
|
|
|
/>
|
2023-03-15 11:53:17 -07:00
|
|
|
</Text>
|
|
|
|
</Stack>
|
|
|
|
);
|
|
|
|
|
2022-12-12 14:36:56 -08:00
|
|
|
/** Page to display a group. */
|
2022-12-15 14:51:30 -08:00
|
|
|
const GroupPage: React.FC<IGroupPage> = ({ params, children }) => {
|
2022-12-16 15:33:07 -08:00
|
|
|
const intl = useIntl();
|
2023-03-23 12:20:19 -07:00
|
|
|
const features = useFeatures();
|
2022-12-15 14:51:30 -08:00
|
|
|
const match = useRouteMatch();
|
2023-06-25 10:35:09 -07:00
|
|
|
const { account: me } = useOwnAccount();
|
2022-12-12 14:36:56 -08:00
|
|
|
|
2023-04-17 12:28:20 -07:00
|
|
|
const id = params?.groupId || '';
|
2022-12-15 14:51:30 -08:00
|
|
|
|
2023-03-02 11:40:36 -08:00
|
|
|
const { group } = useGroup(id);
|
2023-03-20 18:02:58 -07:00
|
|
|
const { accounts: pending } = useGroupMembershipRequests(id);
|
2022-12-12 14:36:56 -08:00
|
|
|
|
2023-03-15 11:53:17 -07:00
|
|
|
const isMember = !!group?.relationship?.member;
|
|
|
|
const isBlocked = group?.relationship?.blocked_by;
|
2023-03-02 11:40:36 -08:00
|
|
|
const isPrivate = group?.locked;
|
2023-04-26 12:53:52 -07:00
|
|
|
const isDeleted = !!group?.deleted_at;
|
2022-12-12 14:36:56 -08:00
|
|
|
|
2023-03-23 12:20:19 -07:00
|
|
|
const tabItems = useMemo(() => {
|
|
|
|
const items = [];
|
|
|
|
items.push({
|
2022-12-16 15:33:07 -08:00
|
|
|
text: intl.formatMessage(messages.all),
|
2023-04-17 12:42:08 -07:00
|
|
|
to: `/group/${group?.slug}`,
|
|
|
|
name: '/group/:groupSlug',
|
2023-03-23 12:20:19 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
if (features.groupsTags) {
|
|
|
|
items.push({
|
|
|
|
text: intl.formatMessage(messages.tags),
|
2023-04-17 12:52:43 -07:00
|
|
|
to: `/group/${group?.slug}/tags`,
|
|
|
|
name: '/group/:groupSlug/tags',
|
2023-03-23 12:20:19 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-05-05 05:35:21 -07:00
|
|
|
items.push(
|
|
|
|
{
|
|
|
|
text: intl.formatMessage(messages.media),
|
|
|
|
to: `/group/${group?.slug}/media`,
|
|
|
|
name: '/group/:groupSlug/media',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
text: intl.formatMessage(messages.members),
|
|
|
|
to: `/group/${group?.slug}/members`,
|
|
|
|
name: '/group/:groupSlug/members',
|
|
|
|
count: pending.length,
|
|
|
|
},
|
|
|
|
);
|
2023-03-23 12:20:19 -07:00
|
|
|
|
|
|
|
return items;
|
2023-06-05 08:11:57 -07:00
|
|
|
}, [features.groupsTags, pending.length, group?.slug]);
|
2022-12-16 15:33:07 -08:00
|
|
|
|
2023-03-15 11:53:17 -07:00
|
|
|
const renderChildren = () => {
|
2023-04-26 12:53:52 -07:00
|
|
|
if (isDeleted) {
|
|
|
|
return <DeletedBlankslate />;
|
|
|
|
} else if (!isMember && isPrivate) {
|
2023-03-15 11:53:17 -07:00
|
|
|
return <PrivacyBlankslate />;
|
|
|
|
} else if (isBlocked) {
|
|
|
|
return <BlockedBlankslate group={group} />;
|
|
|
|
} else {
|
|
|
|
return children;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-12-12 14:36:56 -08:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Layout.Main>
|
2023-04-11 05:55:17 -07:00
|
|
|
<Column size='lg' label={group ? group.display_name : ''} withHeader={false}>
|
2022-12-15 14:51:30 -08:00
|
|
|
<GroupHeader group={group} />
|
2022-12-12 14:36:56 -08:00
|
|
|
|
2022-12-15 14:51:30 -08:00
|
|
|
<Tabs
|
2023-06-05 08:11:57 -07:00
|
|
|
key={`group-tabs-${id}`}
|
2023-03-23 12:20:19 -07:00
|
|
|
items={tabItems}
|
2022-12-15 14:51:30 -08:00
|
|
|
activeItem={match.path}
|
|
|
|
/>
|
2022-12-12 14:36:56 -08:00
|
|
|
|
2023-03-15 11:53:17 -07:00
|
|
|
{renderChildren()}
|
2022-12-12 14:36:56 -08:00
|
|
|
</Column>
|
|
|
|
|
|
|
|
{!me && (
|
|
|
|
<BundleContainer fetchComponent={CtaBanner}>
|
|
|
|
{Component => <Component key='cta-banner' />}
|
|
|
|
</BundleContainer>
|
|
|
|
)}
|
|
|
|
</Layout.Main>
|
|
|
|
|
|
|
|
<Layout.Aside>
|
|
|
|
{!me && (
|
|
|
|
<BundleContainer fetchComponent={SignUpPanel}>
|
|
|
|
{Component => <Component key='sign-up-panel' />}
|
|
|
|
</BundleContainer>
|
|
|
|
)}
|
2022-12-18 04:17:45 -08:00
|
|
|
<BundleContainer fetchComponent={GroupMediaPanel}>
|
|
|
|
{Component => <Component group={group} />}
|
|
|
|
</BundleContainer>
|
2023-03-21 14:34:15 -07:00
|
|
|
<BundleContainer fetchComponent={SuggestedGroupsPanel}>
|
|
|
|
{Component => <Component />}
|
|
|
|
</BundleContainer>
|
2022-12-12 14:36:56 -08:00
|
|
|
<LinkFooter key='link-footer' />
|
|
|
|
</Layout.Aside>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2023-04-17 12:28:20 -07:00
|
|
|
export default GroupLookupHoc(GroupPage as any) as any;
|