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 156 deletions

View File

@ -1,50 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl } from 'react-intl';
import Avatar from '../../../components/avatar';
import DisplayName from '../../../components/display_name';
import IconButton from '../../../components/icon_button';
import Permalink from '../../../components/permalink';
const messages = defineMessages({
authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
});
export default @injectIntl
class AccountAuthorize extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.record.isRequired,
onAuthorize: PropTypes.func.isRequired,
onReject: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
render() {
const { intl, account, onAuthorize, onReject } = this.props;
const content = { __html: account.get('note_emojified') };
return (
<div className='account-authorize__wrapper'>
<div className='account-authorize'>
<Permalink href={`/@${account.get('acct')}`} to={`/@${account.get('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>
);
}
}

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

@ -1,27 +0,0 @@
import { connect } from 'react-redux';
import { authorizeFollowRequest, rejectFollowRequest } from '../../../actions/accounts';
import { makeGetAccount } from '../../../selectors';
import AccountAuthorize from '../components/account_authorize';
const makeMapStateToProps = () => {
const getAccount = makeGetAccount();
const mapStateToProps = (state, props) => ({
account: getAccount(state, props.id),
});
return mapStateToProps;
};
const mapDispatchToProps = (dispatch, { id }) => ({
onAuthorize() {
dispatch(authorizeFollowRequest(id));
},
onReject() {
dispatch(rejectFollowRequest(id));
},
});
export default connect(makeMapStateToProps, mapDispatchToProps)(AccountAuthorize);

View File

@ -1,75 +0,0 @@
import { debounce } from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { Spinner } from 'soapbox/components/ui';
import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts';
import ScrollableList from '../../components/scrollable_list';
import Column from '../ui/components/column';
import AccountAuthorizeContainer from './containers/account_authorize_container';
const messages = defineMessages({
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
});
const mapStateToProps = state => ({
accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
hasMore: !!state.getIn(['user_lists', 'follow_requests', 'next']),
});
export default @connect(mapStateToProps)
@injectIntl
class FollowRequests extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
hasMore: PropTypes.bool,
accountIds: ImmutablePropTypes.orderedSet,
intl: PropTypes.object.isRequired,
};
componentDidMount() {
this.props.dispatch(fetchFollowRequests());
}
handleLoadMore = debounce(() => {
this.props.dispatch(expandFollowRequests());
}, 300, { leading: true });
render() {
const { intl, accountIds, hasMore } = this.props;
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' labellabel={intl.formatMessage(messages.heading)}>
<ScrollableList
scrollKey='follow_requests'
onLoadMore={this.handleLoadMore}
hasMore={hasMore}
emptyMessage={emptyMessage}
>
{accountIds.map(id =>
<AccountAuthorizeContainer key={id} id={id} />,
)}
</ScrollableList>
</Column>
);
}
}

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}
className='space-y-4'
>
{accountIds.map(id =>
{accountIds.map((id: string) =>
<AccountContainer key={id} id={id} />,
)}
</ScrollableList>

View File

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