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

View File

@ -117,6 +117,7 @@ import {
Mutes, Mutes,
NewStatus, NewStatus,
Notifications, Notifications,
OutgoingFollowRequests,
PasswordReset, PasswordReset,
PinnedStatuses, PinnedStatuses,
PlFeConfig, 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} />} {features.chats && <WrappedRoute path='/chats/:chatId' layout={ChatsLayout} component={ChatIndex} content={children} />}
<WrappedRoute path='/follow_requests' layout={DefaultLayout} component={FollowRequests} 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} /> <WrappedRoute path='/blocks' layout={DefaultLayout} component={Blocks} content={children} />
{features.federating && <WrappedRoute path='/domain_blocks' layout={DefaultLayout} component={DomainBlocks} content={children} />} {features.federating && <WrappedRoute path='/domain_blocks' layout={DefaultLayout} component={DomainBlocks} content={children} />}
<WrappedRoute path='/mutes' layout={DefaultLayout} component={Mutes} 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 Mutes = lazy(() => import('pl-fe/features/mutes'));
export const NewStatus = lazy(() => import('pl-fe/features/new-status')); export const NewStatus = lazy(() => import('pl-fe/features/new-status'));
export const Notifications = lazy(() => import('pl-fe/features/notifications')); 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 PasswordReset = lazy(() => import('pl-fe/features/auth-login/components/password-reset'));
export const PinnedStatuses = lazy(() => import('pl-fe/features/pinned-statuses')); export const PinnedStatuses = lazy(() => import('pl-fe/features/pinned-statuses'));
export const PlFeConfig = lazy(() => import('pl-fe/features/pl-fe-config')); export const PlFeConfig = lazy(() => import('pl-fe/features/pl-fe-config'));

View File

@ -403,6 +403,7 @@
"column.migration": "Account migration", "column.migration": "Account migration",
"column.mutes": "Mutes", "column.mutes": "Mutes",
"column.notifications": "Notifications", "column.notifications": "Notifications",
"column.outgoing_follow_requests": "Outgoing follow requests",
"column.pins": "Pinned posts", "column.pins": "Pinned posts",
"column.plfe_config": "Front-end configuration", "column.plfe_config": "Front-end configuration",
"column.preferences": "Preferences", "column.preferences": "Preferences",
@ -728,6 +729,7 @@
"empty_column.mutes": "You haven't muted any users yet.", "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": "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.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.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.quotes": "This post has not been quoted yet.",
"empty_column.remote": "There is nothing here! Manually follow users from {instance} to fill it up.", "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 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 useAcceptFollowRequestMutation = (accountId: string) => {
const client = useClient(); const client = useClient();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -73,6 +78,7 @@ export {
appendFollowRequest, appendFollowRequest,
useFollowRequests, useFollowRequests,
useFollowRequestsCount, useFollowRequestsCount,
useOutgoingFollowRequests,
useAcceptFollowRequestMutation, useAcceptFollowRequestMutation,
useRejectFollowRequestMutation, useRejectFollowRequestMutation,
prefetchFollowRequests, prefetchFollowRequests,