diff --git a/packages/pl-fe/src/features/follow-requests/components/follow-requests-tabs.tsx b/packages/pl-fe/src/features/follow-requests/components/follow-requests-tabs.tsx
new file mode 100644
index 000000000..a35e288da
--- /dev/null
+++ b/packages/pl-fe/src/features/follow-requests/components/follow-requests-tabs.tsx
@@ -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 ;
+};
+
+export { FollowRequestsTabs as default };
diff --git a/packages/pl-fe/src/features/follow-requests/components/outgoing-follow-requests.tsx b/packages/pl-fe/src/features/follow-requests/components/outgoing-follow-requests.tsx
new file mode 100644
index 000000000..dea031ed4
--- /dev/null
+++ b/packages/pl-fe/src/features/follow-requests/components/outgoing-follow-requests.tsx
@@ -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 ? (
+ fetchNextPage({ cancelRefetch: false })}
+ emptyMessage={}
+ itemClassName='p-2.5'
+ >
+ {accountIds.map(id =>
+ ,
+ )}
+
+ ) : ;
+
+ return (
+
+
+
+ {body}
+
+ );
+};
+
+export { OutgoingFollowRequests as default };
diff --git a/packages/pl-fe/src/features/follow-requests/index.tsx b/packages/pl-fe/src/features/follow-requests/index.tsx
index 27c9b64dd..5c14e2a92 100644
--- a/packages/pl-fe/src/features/follow-requests/index.tsx
+++ b/packages/pl-fe/src/features/follow-requests/index.tsx
@@ -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 (
-
-
-
- );
- }
-
- const emptyMessage = ;
+ const body = accountIds ? (
+ fetchNextPage({ cancelRefetch: false })}
+ emptyMessage={}
+ >
+ {accountIds.map(id =>
+ ,
+ )}
+
+ ) : ;
return (
- fetchNextPage({ cancelRefetch: false })}
- emptyMessage={emptyMessage}
- >
- {accountIds.map(id =>
- ,
- )}
-
+
+
+ {body}
);
};
diff --git a/packages/pl-fe/src/features/ui/index.tsx b/packages/pl-fe/src/features/ui/index.tsx
index e2d9afcc4..5a63f30e1 100644
--- a/packages/pl-fe/src/features/ui/index.tsx
+++ b/packages/pl-fe/src/features/ui/index.tsx
@@ -117,6 +117,7 @@ import {
Mutes,
NewStatus,
Notifications,
+ OutgoingFollowRequests,
PasswordReset,
PinnedStatuses,
PlFeConfig,
@@ -252,6 +253,7 @@ const SwitchingColumnsArea: React.FC = React.memo(({ chil
{features.chats && }
+ {features.outgoingFollowRequests && }
{features.federating && }
diff --git a/packages/pl-fe/src/features/ui/util/async-components.ts b/packages/pl-fe/src/features/ui/util/async-components.ts
index 0561a2bef..29451ae6e 100644
--- a/packages/pl-fe/src/features/ui/util/async-components.ts
+++ b/packages/pl-fe/src/features/ui/util/async-components.ts
@@ -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'));
diff --git a/packages/pl-fe/src/locales/en.json b/packages/pl-fe/src/locales/en.json
index 0cb1ce219..1d4de3c50 100644
--- a/packages/pl-fe/src/locales/en.json
+++ b/packages/pl-fe/src/locales/en.json
@@ -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.",
diff --git a/packages/pl-fe/src/queries/accounts/use-follow-requests.ts b/packages/pl-fe/src/queries/accounts/use-follow-requests.ts
index 7e703469a..9f4092397 100644
--- a/packages/pl-fe/src/queries/accounts/use-follow-requests.ts
+++ b/packages/pl-fe/src/queries/accounts/use-follow-requests.ts
@@ -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,