pl-fe: Display outgoing follow requests

Signed-off-by: mkljczk <git@mkljczk.pl>
This commit is contained in:
mkljczk
2025-03-13 12:46:57 +01:00
parent f0cd921109
commit ee5cacd176
7 changed files with 106 additions and 19 deletions

View File

@@ -0,0 +1,35 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { useRouteMatch } from 'react-router-dom';
import Tabs from 'pl-fe/components/ui/tabs';
import { useFeatures } from 'pl-fe/hooks/use-features';
const messages = defineMessages({
followRequests: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
outgoingFollowRequests: { id: 'column.outgoing_follow_requests', defaultMessage: 'Outgoing follow requests' },
});
const FollowRequestsTabs = () => {
const intl = useIntl();
const match = useRouteMatch();
const features = useFeatures();
if (!features.outgoingFollowRequests) {
return null;
}
const tabs = [{
name: '/follow_requests',
text: intl.formatMessage(messages.followRequests),
to: '/follow_requests',
}, {
name: '/outgoing_follow_requests',
text: intl.formatMessage(messages.outgoingFollowRequests),
to: '/outgoing_follow_requests',
}];
return <Tabs items={tabs} activeItem={match.path} />;
};
export { FollowRequestsTabs as default };

View File

@@ -0,0 +1,44 @@
import React from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import ScrollableList from 'pl-fe/components/scrollable-list';
import Column from 'pl-fe/components/ui/column';
import Spinner from 'pl-fe/components/ui/spinner';
import AccountContainer from 'pl-fe/containers/account-container';
import { useOutgoingFollowRequests } from 'pl-fe/queries/accounts/use-follow-requests';
import FollowRequestsTabs from './follow-requests-tabs';
const messages = defineMessages({
heading: { id: 'column.outgoing_follow_requests', defaultMessage: 'Outgoing follow requests' },
});
const OutgoingFollowRequests: React.FC = () => {
const intl = useIntl();
const { data: accountIds, isLoading, hasNextPage, fetchNextPage } = useOutgoingFollowRequests();
const body = accountIds ? (
<ScrollableList
hasMore={hasNextPage}
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
onLoadMore={() => fetchNextPage({ cancelRefetch: false })}
emptyMessage={<FormattedMessage id='empty_column.outgoing_follow_requests' defaultMessage="You don't have any outgoing follow requests yet. When you try to follow a user, it will show up here." />}
itemClassName='p-2.5'
>
{accountIds.map(id =>
<AccountContainer key={id} id={id} />,
)}
</ScrollableList>
) : <Spinner />;
return (
<Column label={intl.formatMessage(messages.heading)}>
<FollowRequestsTabs />
{body}
</Column>
);
};
export { OutgoingFollowRequests as default };

View File

@@ -7,6 +7,7 @@ import Spinner from 'pl-fe/components/ui/spinner';
import { useFollowRequests } from 'pl-fe/queries/accounts/use-follow-requests';
import AccountAuthorize from './components/account-authorize';
import FollowRequestsTabs from './components/follow-requests-tabs';
const messages = defineMessages({
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
@@ -17,28 +18,24 @@ const FollowRequests: React.FC = () => {
const { data: accountIds, isLoading, hasNextPage, fetchNextPage } = useFollowRequests();
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." />;
const body = accountIds ? (
<ScrollableList
hasMore={hasNextPage}
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
onLoadMore={() => fetchNextPage({ cancelRefetch: false })}
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." />}
>
{accountIds.map(id =>
<AccountAuthorize key={id} id={id} />,
)}
</ScrollableList>
) : <Spinner />;
return (
<Column label={intl.formatMessage(messages.heading)}>
<ScrollableList
hasMore={hasNextPage}
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
onLoadMore={() => fetchNextPage({ cancelRefetch: false })}
emptyMessage={emptyMessage}
>
{accountIds.map(id =>
<AccountAuthorize key={id} id={id} />,
)}
</ScrollableList>
<FollowRequestsTabs />
{body}
</Column>
);
};

View File

@@ -117,6 +117,7 @@ import {
Mutes,
NewStatus,
Notifications,
OutgoingFollowRequests,
PasswordReset,
PinnedStatuses,
PlFeConfig,
@@ -252,6 +253,7 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = React.memo(({ chil
{features.chats && <WrappedRoute path='/chats/:chatId' layout={ChatsLayout} component={ChatIndex} content={children} />}
<WrappedRoute path='/follow_requests' layout={DefaultLayout} component={FollowRequests} content={children} />
{features.outgoingFollowRequests && <WrappedRoute path='/outgoing_follow_requests' layout={DefaultLayout} component={OutgoingFollowRequests} content={children} />}
<WrappedRoute path='/blocks' layout={DefaultLayout} component={Blocks} content={children} />
{features.federating && <WrappedRoute path='/domain_blocks' layout={DefaultLayout} component={DomainBlocks} content={children} />}
<WrappedRoute path='/mutes' layout={DefaultLayout} component={Mutes} content={children} />

View File

@@ -70,6 +70,7 @@ export const ModerationLog = lazy(() => import('pl-fe/features/admin/moderation-
export const Mutes = lazy(() => import('pl-fe/features/mutes'));
export const NewStatus = lazy(() => import('pl-fe/features/new-status'));
export const Notifications = lazy(() => import('pl-fe/features/notifications'));
export const OutgoingFollowRequests = lazy(() => import('pl-fe/features/follow-requests/components/outgoing-follow-requests'));
export const PasswordReset = lazy(() => import('pl-fe/features/auth-login/components/password-reset'));
export const PinnedStatuses = lazy(() => import('pl-fe/features/pinned-statuses'));
export const PlFeConfig = lazy(() => import('pl-fe/features/pl-fe-config'));

View File

@@ -403,6 +403,7 @@
"column.migration": "Account migration",
"column.mutes": "Mutes",
"column.notifications": "Notifications",
"column.outgoing_follow_requests": "Outgoing follow requests",
"column.pins": "Pinned posts",
"column.plfe_config": "Front-end configuration",
"column.preferences": "Preferences",
@@ -728,6 +729,7 @@
"empty_column.mutes": "You haven't muted any users yet.",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.notifications_filtered": "You don't have any notifications of this type yet.",
"empty_column.outgoing_follow_requests": "You don't have any outgoing follow requests yet. When you try to follow a user, it will show up here.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
"empty_column.quotes": "This post has not been quoted yet.",
"empty_column.remote": "There is nothing here! Manually follow users from {instance} to fill it up.",

View File

@@ -35,6 +35,11 @@ const useFollowRequests = makeUseFollowRequests((data) => data.pages.map(page =>
const useFollowRequestsCount = makeUseFollowRequests((data) => data.pages.map(page => page.items).flat().length);
const useOutgoingFollowRequests = makePaginatedResponseQuery(
() => ['accountsLists', 'outgoingFollowRequests'],
(client) => client.myAccount.getOutgoingFollowRequests().then(minifyAccountList),
);
const useAcceptFollowRequestMutation = (accountId: string) => {
const client = useClient();
const dispatch = useAppDispatch();
@@ -73,6 +78,7 @@ export {
appendFollowRequest,
useFollowRequests,
useFollowRequestsCount,
useOutgoingFollowRequests,
useAcceptFollowRequestMutation,
useRejectFollowRequestMutation,
prefetchFollowRequests,