Typescript, FC

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2022-04-11 23:02:37 +02:00
parent 2943b91034
commit ae396544a7
7 changed files with 125 additions and 4 deletions

View file

@ -0,0 +1,61 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { useDispatch } from 'react-redux';
import { authorizeFollowRequest, rejectFollowRequest } from 'soapbox/actions/accounts';
import Avatar from 'soapbox/components/avatar';
import DisplayName from 'soapbox/components/display_name';
import IconButton from 'soapbox/components/icon_button';
import Permalink from 'soapbox/components/permalink';
import { useAppSelector } from 'soapbox/hooks';
import { makeGetAccount } from 'soapbox/selectors';
const messages = defineMessages({
authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
});
const getAccount = makeGetAccount();
interface IAccountAuthorize {
id: string,
}
const AccountAuthorize: React.FC<IAccountAuthorize> = ({ id }) => {
const intl = useIntl();
const dispatch = useDispatch();
const account = useAppSelector((state) => getAccount(state, id));
const onAuthorize = () => {
dispatch(authorizeFollowRequest(id));
};
const onReject = () => {
dispatch(rejectFollowRequest(id));
};
if (!account) return null;
const content = { __html: account.note_emojified };
return (
<div className='account-authorize__wrapper'>
<div className='account-authorize'>
<Permalink href={`/@${account.acct}`} to={`/@${account.acct}`} className='detailed-status__display-name'>
<div className='account-authorize__avatar'><Avatar account={account} size={48} /></div>
<DisplayName account={account} />
</Permalink>
<div className='account__header__content' dangerouslySetInnerHTML={content} />
</div>
<div className='account--panel'>
<div className='account--panel__button'><IconButton title={intl.formatMessage(messages.authorize)} src={require('@tabler/icons/icons/check.svg')} onClick={onAuthorize} /></div>
<div className='account--panel__button'><IconButton title={intl.formatMessage(messages.reject)} src={require('@tabler/icons/icons/x.svg')} onClick={onReject} /></div>
</div>
</div>
);
};
export default AccountAuthorize;

View file

@ -0,0 +1,60 @@
import { debounce } from 'lodash';
import React from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { useDispatch } from 'react-redux';
import { fetchFollowRequests, expandFollowRequests } from 'soapbox/actions/accounts';
import ScrollableList from 'soapbox/components/scrollable_list';
import { Spinner } from 'soapbox/components/ui';
import { useAppSelector } from 'soapbox/hooks';
import Column from '../ui/components/column';
import AccountAuthorize from './components/account_authorize';
const messages = defineMessages({
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
});
const handleLoadMore = debounce((dispatch) => {
dispatch(expandFollowRequests());
}, 300, { leading: true });
const FollowRequests: React.FC = () => {
const dispatch = useDispatch();
const intl = useIntl();
const accountIds = useAppSelector<string[]>((state) => state.user_lists.getIn(['follow_requests', 'items']));
const hasMore = useAppSelector((state) => !!state.user_lists.getIn(['follow_requests', 'next']));
React.useEffect(() => {
dispatch(fetchFollowRequests());
}, []);
if (!accountIds) {
return (
<Column>
<Spinner />
</Column>
);
}
const emptyMessage = <FormattedMessage id='empty_column.follow_requests' defaultMessage="You don't have any follow requests yet. When you receive one, it will show up here." />;
return (
<Column icon='user-plus' label={intl.formatMessage(messages.heading)}>
<ScrollableList
scrollKey='follow_requests'
onLoadMore={() => handleLoadMore(dispatch)}
hasMore={hasMore}
emptyMessage={emptyMessage}
>
{accountIds.map(id =>
<AccountAuthorize key={id} id={id} />,
)}
</ScrollableList>
</Column>
);
};
export default FollowRequests;

View file

@ -47,7 +47,7 @@ const Mutes: React.FC = () => {
emptyMessage={emptyMessage} emptyMessage={emptyMessage}
className='space-y-4' className='space-y-4'
> >
{accountIds.map(id => {accountIds.map((id: string) =>
<AccountContainer key={id} id={id} />, <AccountContainer key={id} id={id} />,
)} )}
</ScrollableList> </ScrollableList>

View file

@ -4,9 +4,9 @@ import type { Status as StatusEntity } from 'soapbox/types/entities';
export const shouldFilter = (status: StatusEntity, columnSettings: any) => { export const shouldFilter = (status: StatusEntity, columnSettings: any) => {
const shows = ImmutableMap({ const shows = ImmutableMap({
reblog: status.reblog !== null, reblog: status.get('reblog') !== null,
reply: status.in_reply_to_id !== null, reply: status.get('in_reply_to_id') !== null,
direct: status.visibility === 'direct', direct: status.get('visibility') === 'direct',
}); });
return shows.some((value, key) => { return shows.some((value, key) => {