From 573f6a59100ccdfc8bbacf87a14d4f7083401f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicole=20Miko=C5=82ajczyk?= Date: Thu, 15 May 2025 21:02:42 +0200 Subject: [PATCH] pl-fe: move more files around MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicole Mikołajczyk --- .../compose/components/privacy-dropdown.tsx | 2 +- .../pl-fe/src/features/directory/index.tsx | 108 ------------------ .../components/account-authorize.tsx | 39 ------- .../components/follow-requests-tabs.tsx | 35 ------ .../src/features/follow-requests/index.tsx | 44 ------- .../lists/components/new-list-form.tsx | 66 ----------- .../src/features/ui/util/async-components.ts | 16 +-- .../src/modals/list-adder-modal/index.tsx | 3 +- .../account-lists/circles.tsx} | 7 +- .../account-lists/directory.tsx} | 104 ++++++++++++++++- .../account-lists/follow-recommendations.tsx} | 4 +- .../pages/account-lists/follow-requests.tsx | 102 +++++++++++++++++ .../account-lists/followers.tsx} | 6 +- .../account-lists/following.tsx} | 6 +- .../account-lists/lists.tsx} | 64 ++++++++++- .../outgoing-follow-requests.tsx | 6 +- 16 files changed, 287 insertions(+), 325 deletions(-) delete mode 100644 packages/pl-fe/src/features/directory/index.tsx delete mode 100644 packages/pl-fe/src/features/follow-requests/components/account-authorize.tsx delete mode 100644 packages/pl-fe/src/features/follow-requests/components/follow-requests-tabs.tsx delete mode 100644 packages/pl-fe/src/features/follow-requests/index.tsx delete mode 100644 packages/pl-fe/src/features/lists/components/new-list-form.tsx rename packages/pl-fe/src/{features/circles/index.tsx => pages/account-lists/circles.tsx} (95%) rename packages/pl-fe/src/{features/directory/components/account-card.tsx => pages/account-lists/directory.tsx} (53%) rename packages/pl-fe/src/{features/follow-recommendations/index.tsx => pages/account-lists/follow-recommendations.tsx} (94%) create mode 100644 packages/pl-fe/src/pages/account-lists/follow-requests.tsx rename packages/pl-fe/src/{features/followers/index.tsx => pages/account-lists/followers.tsx} (93%) rename packages/pl-fe/src/{features/following/index.tsx => pages/account-lists/following.tsx} (93%) rename packages/pl-fe/src/{features/lists/index.tsx => pages/account-lists/lists.tsx} (51%) rename packages/pl-fe/src/{features/follow-requests/components => pages/account-lists}/outgoing-follow-requests.tsx (90%) diff --git a/packages/pl-fe/src/features/compose/components/privacy-dropdown.tsx b/packages/pl-fe/src/features/compose/components/privacy-dropdown.tsx index 7ce95950c..8a58aae4d 100644 --- a/packages/pl-fe/src/features/compose/components/privacy-dropdown.tsx +++ b/packages/pl-fe/src/features/compose/components/privacy-dropdown.tsx @@ -4,10 +4,10 @@ import { useIntl, defineMessages, IntlShape } from 'react-intl'; import { changeComposeFederated, changeComposeVisibility } from 'pl-fe/actions/compose'; import DropdownMenu, { MenuItem } from 'pl-fe/components/dropdown-menu'; import Button from 'pl-fe/components/ui/button'; -import { getOrderedLists } from 'pl-fe/features/lists'; import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; import { useCompose } from 'pl-fe/hooks/use-compose'; import { useFeatures } from 'pl-fe/hooks/use-features'; +import { getOrderedLists } from 'pl-fe/pages/account-lists/lists'; import { useCircles } from 'pl-fe/queries/accounts/use-circles'; import { useLists } from 'pl-fe/queries/accounts/use-lists'; diff --git a/packages/pl-fe/src/features/directory/index.tsx b/packages/pl-fe/src/features/directory/index.tsx deleted file mode 100644 index 656061982..000000000 --- a/packages/pl-fe/src/features/directory/index.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import clsx from 'clsx'; -import React from 'react'; -import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; -import { useSearchParams } from 'react-router-dom-v5-compat'; - -import LoadMore from 'pl-fe/components/load-more'; -import { RadioGroup, RadioItem } from 'pl-fe/components/radio'; -import { CardTitle } from 'pl-fe/components/ui/card'; -import Column from 'pl-fe/components/ui/column'; -import Stack from 'pl-fe/components/ui/stack'; -import { useFeatures } from 'pl-fe/hooks/use-features'; -import { useInstance } from 'pl-fe/hooks/use-instance'; -import { useDirectory } from 'pl-fe/queries/accounts/use-directory'; - -import AccountCard from './components/account-card'; - -const messages = defineMessages({ - title: { id: 'column.directory', defaultMessage: 'Browse profiles' }, - recentlyActive: { id: 'directory.recently_active', defaultMessage: 'Recently active' }, - newArrivals: { id: 'directory.new_arrivals', defaultMessage: 'New arrivals' }, - local: { id: 'directory.local', defaultMessage: 'From {domain} only' }, - federated: { id: 'directory.federated', defaultMessage: 'From known fediverse' }, -}); - -const Directory = () => { - const intl = useIntl(); - const [params, setParams] = useSearchParams(); - const instance = useInstance(); - const features = useFeatures(); - - const order = (params.get('order') || 'active') as 'active' | 'new'; - const local = !!params.get('local'); - - const { data: accountIds = [], isLoading, hasNextPage, fetchNextPage } = useDirectory(order, local); - - const handleChangeOrder: React.ChangeEventHandler = e => { - setParams({ local: local ? 'true' : '', order: e.target.value }); - }; - - const handleChangeLocal: React.ChangeEventHandler = e => { - setParams({ local: e.target.value === '1' ? 'true' : '', order }); - }; - - const handleLoadMore = () => { - fetchNextPage({ cancelRefetch: false }); - }; - - return ( - - -
- - } /> - - - - - - - - {features.federating && ( - - } /> - - - - - - - )} -
- -
- {accountIds.map((accountId) => ( - ), - )} -
- - {hasNextPage && } -
-
- ); -}; - -export { Directory as default }; diff --git a/packages/pl-fe/src/features/follow-requests/components/account-authorize.tsx b/packages/pl-fe/src/features/follow-requests/components/account-authorize.tsx deleted file mode 100644 index 691821f02..000000000 --- a/packages/pl-fe/src/features/follow-requests/components/account-authorize.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; - -import { useAccount } from 'pl-fe/api/hooks/accounts/use-account'; -import Account from 'pl-fe/components/account'; -import { AuthorizeRejectButtons } from 'pl-fe/components/authorize-reject-buttons'; -import { useAcceptFollowRequestMutation, useRejectFollowRequestMutation } from 'pl-fe/queries/accounts/use-follow-requests'; - -interface IAccountAuthorize { - id: string; -} - -const AccountAuthorize: React.FC = ({ id }) => { - const { account } = useAccount(id); - - const { mutate: authorizeFollowRequest } = useAcceptFollowRequestMutation(id); - const { mutate: rejectFollowRequest } = useRejectFollowRequestMutation(id); - - const onAuthorize = () => authorizeFollowRequest(); - const onReject = () => rejectFollowRequest(); - - if (!account) return null; - - return ( -
- - } - /> -
- ); -}; - -export { AccountAuthorize as default }; 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 deleted file mode 100644 index a35e288da..000000000 --- a/packages/pl-fe/src/features/follow-requests/components/follow-requests-tabs.tsx +++ /dev/null @@ -1,35 +0,0 @@ -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/index.tsx b/packages/pl-fe/src/features/follow-requests/index.tsx deleted file mode 100644 index e984fbb0a..000000000 --- a/packages/pl-fe/src/features/follow-requests/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -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 { 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' }, -}); - -const FollowRequests: React.FC = () => { - const intl = useIntl(); - - const { data: accountIds, isLoading, hasNextPage, fetchNextPage } = useFollowRequests(); - - const body = accountIds ? ( - fetchNextPage({ cancelRefetch: false })} - emptyMessage={} - > - {accountIds.map(id => - , - )} - - ) : ; - - return ( - - - - {body} - - ); -}; - -export { FollowRequests as default }; diff --git a/packages/pl-fe/src/features/lists/components/new-list-form.tsx b/packages/pl-fe/src/features/lists/components/new-list-form.tsx deleted file mode 100644 index 72c17fd59..000000000 --- a/packages/pl-fe/src/features/lists/components/new-list-form.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react'; -import { defineMessages, useIntl } from 'react-intl'; - -import { changeListEditorTitle } from 'pl-fe/actions/lists'; -import Button from 'pl-fe/components/ui/button'; -import Form from 'pl-fe/components/ui/form'; -import HStack from 'pl-fe/components/ui/hstack'; -import Input from 'pl-fe/components/ui/input'; -import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; -import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; -import { useCreateList } from 'pl-fe/queries/accounts/use-lists'; - -const messages = defineMessages({ - label: { id: 'lists.new.title_placeholder', defaultMessage: 'New list title' }, - title: { id: 'lists.new.create', defaultMessage: 'Add list' }, - create: { id: 'lists.new.create_title', defaultMessage: 'Add list' }, -}); - -const NewListForm: React.FC = () => { - const dispatch = useAppDispatch(); - const intl = useIntl(); - - const { title: value, isSubmitting: disabled } = useAppSelector((state) => state.listEditor); - - const { mutate: createList } = useCreateList(); - - const handleChange = (e: React.ChangeEvent) => { - dispatch(changeListEditorTitle(e.target.value)); - }; - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - createList({ title: value }); - }; - - const label = intl.formatMessage(messages.label); - const create = intl.formatMessage(messages.create); - - return ( -
- - - - - -
- ); -}; - -export { NewListForm as default }; 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 eff16189f..3f37e7b80 100644 --- a/packages/pl-fe/src/features/ui/util/async-components.ts +++ b/packages/pl-fe/src/features/ui/util/async-components.ts @@ -77,23 +77,23 @@ export const AccountGallery = lazy(() => import('pl-fe/features/account-gallery' export const AccountTimeline = lazy(() => import('pl-fe/features/account-timeline')); export const BookmarkFolders = lazy(() => import('pl-fe/features/bookmark-folders')); export const Circle = lazy(() => import('pl-fe/features/circle')); -export const Circles = lazy(() => import('pl-fe/features/circles')); +export const Circles = lazy(() => import('pl-fe/pages/account-lists/circles')); export const ComposeEditor = lazy(() => import('pl-fe/features/compose/editor')); export const ComposeEvent = lazy(() => import('pl-fe/features/compose-event')); -export const Directory = lazy(() => import('pl-fe/features/directory')); +export const Directory = lazy(() => import('pl-fe/pages/account-lists/directory')); export const DraftStatuses = lazy(() => import('pl-fe/features/draft-statuses')); export const EventDiscussion = lazy(() => import('pl-fe/features/event/event-discussion')); export const EventInformation = lazy(() => import('pl-fe/features/event/event-information')); export const Events = lazy(() => import('pl-fe/features/events')); export const FollowedTags = lazy(() => import('pl-fe/features/followed-tags')); -export const Followers = lazy(() => import('pl-fe/features/followers')); -export const Following = lazy(() => import('pl-fe/features/following')); -export const FollowRecommendations = lazy(() => import('pl-fe/features/follow-recommendations')); -export const FollowRequests = lazy(() => import('pl-fe/features/follow-requests')); +export const Followers = lazy(() => import('pl-fe/pages/account-lists/followers')); +export const Following = lazy(() => import('pl-fe/pages/account-lists/following')); +export const FollowRecommendations = lazy(() => import('pl-fe/pages/account-lists/follow-recommendations')); +export const FollowRequests = lazy(() => import('pl-fe/pages/account-lists/follow-requests')); export const InteractionRequests = lazy(() => import('pl-fe/features/interaction-requests')); -export const Lists = lazy(() => import('pl-fe/features/lists')); +export const Lists = lazy(() => import('pl-fe/pages/account-lists/lists')); 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 OutgoingFollowRequests = lazy(() => import('pl-fe/pages/account-lists/outgoing-follow-requests')); export const ScheduledStatuses = lazy(() => import('pl-fe/features/scheduled-statuses')); export const Search = lazy(() => import('pl-fe/features/search')); export const Status = lazy(() => import('pl-fe/features/status')); diff --git a/packages/pl-fe/src/modals/list-adder-modal/index.tsx b/packages/pl-fe/src/modals/list-adder-modal/index.tsx index 87063e501..a7a6db8c8 100644 --- a/packages/pl-fe/src/modals/list-adder-modal/index.tsx +++ b/packages/pl-fe/src/modals/list-adder-modal/index.tsx @@ -5,9 +5,8 @@ import { setupListAdder, resetListAdder } from 'pl-fe/actions/lists'; import { CardHeader, CardTitle } from 'pl-fe/components/ui/card'; import Modal from 'pl-fe/components/ui/modal'; import AccountContainer from 'pl-fe/containers/account-container'; -import { getOrderedLists } from 'pl-fe/features/lists'; -import NewListForm from 'pl-fe/features/lists/components/new-list-form'; import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; +import { NewListForm, getOrderedLists } from 'pl-fe/pages/account-lists/lists'; import { useLists } from 'pl-fe/queries/accounts/use-lists'; import List from './components/list'; diff --git a/packages/pl-fe/src/features/circles/index.tsx b/packages/pl-fe/src/pages/account-lists/circles.tsx similarity index 95% rename from packages/pl-fe/src/features/circles/index.tsx rename to packages/pl-fe/src/pages/account-lists/circles.tsx index b9ff28f75..b689c9178 100644 --- a/packages/pl-fe/src/features/circles/index.tsx +++ b/packages/pl-fe/src/pages/account-lists/circles.tsx @@ -11,10 +11,9 @@ import Icon from 'pl-fe/components/ui/icon'; import Input from 'pl-fe/components/ui/input'; import Spinner from 'pl-fe/components/ui/spinner'; import Stack from 'pl-fe/components/ui/stack'; +import { getOrderedLists } from 'pl-fe/pages/account-lists/lists'; import { useCircles, useCreateCircle } from 'pl-fe/queries/accounts/use-circles'; -import { getOrderedLists } from '../lists'; - const messages = defineMessages({ heading: { id: 'column.circles', defaultMessage: 'Circles' }, subheading: { id: 'circles.subheading', defaultMessage: 'Your circles' }, @@ -69,7 +68,7 @@ const NewCircleForm: React.FC = () => { ); }; -const Circles: React.FC = () => { +const CirclesPage: React.FC = () => { const intl = useIntl(); const { data: circles } = useCircles(getOrderedLists); @@ -114,4 +113,4 @@ const Circles: React.FC = () => { ); }; -export { Circles as default }; +export { CirclesPage as default }; diff --git a/packages/pl-fe/src/features/directory/components/account-card.tsx b/packages/pl-fe/src/pages/account-lists/directory.tsx similarity index 53% rename from packages/pl-fe/src/features/directory/components/account-card.tsx rename to packages/pl-fe/src/pages/account-lists/directory.tsx index 73ce96767..e9580c172 100644 --- a/packages/pl-fe/src/features/directory/components/account-card.tsx +++ b/packages/pl-fe/src/pages/account-lists/directory.tsx @@ -1,21 +1,38 @@ +import clsx from 'clsx'; import React from 'react'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { Link } from 'react-router-dom'; +import { useSearchParams } from 'react-router-dom-v5-compat'; import { useAccount } from 'pl-fe/api/hooks/accounts/use-account'; import Account from 'pl-fe/components/account'; import Badge from 'pl-fe/components/badge'; import HoverAccountWrapper from 'pl-fe/components/hover-account-wrapper'; +import LoadMore from 'pl-fe/components/load-more'; import { ParsedContent } from 'pl-fe/components/parsed-content'; +import { RadioGroup, RadioItem } from 'pl-fe/components/radio'; import RelativeTimestamp from 'pl-fe/components/relative-timestamp'; import Avatar from 'pl-fe/components/ui/avatar'; +import { CardTitle } from 'pl-fe/components/ui/card'; +import Column from 'pl-fe/components/ui/column'; import Stack from 'pl-fe/components/ui/stack'; import Text from 'pl-fe/components/ui/text'; import ActionButton from 'pl-fe/features/ui/components/action-button'; import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; +import { useFeatures } from 'pl-fe/hooks/use-features'; +import { useInstance } from 'pl-fe/hooks/use-instance'; +import { useDirectory } from 'pl-fe/queries/accounts/use-directory'; import { useSettingsStore } from 'pl-fe/stores/settings'; import { shortNumberFormat } from 'pl-fe/utils/numbers'; +const messages = defineMessages({ + title: { id: 'column.directory', defaultMessage: 'Browse profiles' }, + recentlyActive: { id: 'directory.recently_active', defaultMessage: 'Recently active' }, + newArrivals: { id: 'directory.new_arrivals', defaultMessage: 'New arrivals' }, + local: { id: 'directory.local', defaultMessage: 'From {domain} only' }, + federated: { id: 'directory.federated', defaultMessage: 'From known fediverse' }, +}); + interface IAccountCard { id: string; } @@ -121,4 +138,87 @@ const AccountCard: React.FC = ({ id }) => { ); }; -export { AccountCard as default }; +const DirectoryPage = () => { + const intl = useIntl(); + const [params, setParams] = useSearchParams(); + const instance = useInstance(); + const features = useFeatures(); + + const order = (params.get('order') || 'active') as 'active' | 'new'; + const local = !!params.get('local'); + + const { data: accountIds = [], isLoading, hasNextPage, fetchNextPage } = useDirectory(order, local); + + const handleChangeOrder: React.ChangeEventHandler = e => { + setParams({ local: local ? 'true' : '', order: e.target.value }); + }; + + const handleChangeLocal: React.ChangeEventHandler = e => { + setParams({ local: e.target.value === '1' ? 'true' : '', order }); + }; + + const handleLoadMore = () => { + fetchNextPage({ cancelRefetch: false }); + }; + + return ( + + +
+ + } /> + + + + + + + + {features.federating && ( + + } /> + + + + + + + )} +
+ +
+ {accountIds.map((accountId) => ( + ), + )} +
+ + {hasNextPage && } +
+
+ ); +}; + +export { DirectoryPage as default }; diff --git a/packages/pl-fe/src/features/follow-recommendations/index.tsx b/packages/pl-fe/src/pages/account-lists/follow-recommendations.tsx similarity index 94% rename from packages/pl-fe/src/features/follow-recommendations/index.tsx rename to packages/pl-fe/src/pages/account-lists/follow-recommendations.tsx index d4e429a93..5c2135bb4 100644 --- a/packages/pl-fe/src/features/follow-recommendations/index.tsx +++ b/packages/pl-fe/src/pages/account-lists/follow-recommendations.tsx @@ -12,7 +12,7 @@ const messages = defineMessages({ heading: { id: 'follow_recommendations.heading', defaultMessage: 'Suggested profiles' }, }); -const FollowRecommendations: React.FC = () => { +const FollowRecommendationsPage: React.FC = () => { const intl = useIntl(); const { data: suggestions, isFetching } = useSuggestions(); @@ -48,4 +48,4 @@ const FollowRecommendations: React.FC = () => { ); }; -export { FollowRecommendations as default }; +export { FollowRecommendationsPage as default }; diff --git a/packages/pl-fe/src/pages/account-lists/follow-requests.tsx b/packages/pl-fe/src/pages/account-lists/follow-requests.tsx new file mode 100644 index 000000000..f772ff350 --- /dev/null +++ b/packages/pl-fe/src/pages/account-lists/follow-requests.tsx @@ -0,0 +1,102 @@ +import React from 'react'; +import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; +import { useRouteMatch } from 'react-router-dom'; + +import { useAccount } from 'pl-fe/api/hooks/accounts/use-account'; +import Account from 'pl-fe/components/account'; +import { AuthorizeRejectButtons } from 'pl-fe/components/authorize-reject-buttons'; +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 Tabs from 'pl-fe/components/ui/tabs'; +import { useFeatures } from 'pl-fe/hooks/use-features'; +import { useAcceptFollowRequestMutation, useFollowRequests, useRejectFollowRequestMutation } from 'pl-fe/queries/accounts/use-follow-requests'; + +const messages = defineMessages({ + heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' }, + followRequests: { id: 'column.follow_requests', defaultMessage: 'Follow requests' }, + outgoingFollowRequests: { id: 'column.outgoing_follow_requests', defaultMessage: 'Outgoing follow requests' }, +}); + +interface IAccountAuthorize { + id: string; +} + +const AccountAuthorize: React.FC = ({ id }) => { + const { account } = useAccount(id); + + const { mutate: authorizeFollowRequest } = useAcceptFollowRequestMutation(id); + const { mutate: rejectFollowRequest } = useRejectFollowRequestMutation(id); + + const onAuthorize = () => authorizeFollowRequest(); + const onReject = () => rejectFollowRequest(); + + if (!account) return null; + + return ( +
+ + } + /> +
+ ); +}; + +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 ; +}; + +const FollowRequestsPage: React.FC = () => { + const intl = useIntl(); + + const { data: accountIds, isLoading, hasNextPage, fetchNextPage } = useFollowRequests(); + + const body = accountIds ? ( + fetchNextPage({ cancelRefetch: false })} + emptyMessage={} + > + {accountIds.map(id => + , + )} + + ) : ; + + return ( + + + + {body} + + ); +}; + +export { FollowRequestsPage as default, FollowRequestsTabs }; diff --git a/packages/pl-fe/src/features/followers/index.tsx b/packages/pl-fe/src/pages/account-lists/followers.tsx similarity index 93% rename from packages/pl-fe/src/features/followers/index.tsx rename to packages/pl-fe/src/pages/account-lists/followers.tsx index 7b9246366..f56a174b4 100644 --- a/packages/pl-fe/src/features/followers/index.tsx +++ b/packages/pl-fe/src/pages/account-lists/followers.tsx @@ -13,14 +13,14 @@ const messages = defineMessages({ heading: { id: 'column.followers', defaultMessage: 'Followers' }, }); -interface IFollowers { +interface IFollowersPage { params?: { username?: string; }; } /** Displays a list of accounts who follow the given account. */ -const Followers: React.FC = ({ params }) => { +const FollowersPage: React.FC = ({ params }) => { const intl = useIntl(); const { account, isUnavailable } = useAccountLookup(params?.username); @@ -74,4 +74,4 @@ const Followers: React.FC = ({ params }) => { ); }; -export { Followers as default }; +export { FollowersPage as default }; diff --git a/packages/pl-fe/src/features/following/index.tsx b/packages/pl-fe/src/pages/account-lists/following.tsx similarity index 93% rename from packages/pl-fe/src/features/following/index.tsx rename to packages/pl-fe/src/pages/account-lists/following.tsx index 1061bab3a..4ccebdb4a 100644 --- a/packages/pl-fe/src/features/following/index.tsx +++ b/packages/pl-fe/src/pages/account-lists/following.tsx @@ -13,14 +13,14 @@ const messages = defineMessages({ heading: { id: 'column.following', defaultMessage: 'Following' }, }); -interface IFollowing { +interface IFollowingPage { params?: { username?: string; }; } /** Displays a list of accounts the given user is following. */ -const Following: React.FC = ({ params }) => { +const FollowingPage: React.FC = ({ params }) => { const intl = useIntl(); const { account, isUnavailable } = useAccountLookup(params?.username); @@ -74,4 +74,4 @@ const Following: React.FC = ({ params }) => { ); }; -export { Following as default }; +export { FollowingPage as default }; diff --git a/packages/pl-fe/src/features/lists/index.tsx b/packages/pl-fe/src/pages/account-lists/lists.tsx similarity index 51% rename from packages/pl-fe/src/features/lists/index.tsx rename to packages/pl-fe/src/pages/account-lists/lists.tsx index 7754527c9..81f282f25 100644 --- a/packages/pl-fe/src/features/lists/index.tsx +++ b/packages/pl-fe/src/pages/account-lists/lists.tsx @@ -1,22 +1,29 @@ import React from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; +import { changeListEditorTitle } from 'pl-fe/actions/lists'; import List, { ListItem } from 'pl-fe/components/list'; +import Button from 'pl-fe/components/ui/button'; import Card from 'pl-fe/components/ui/card'; import Column from 'pl-fe/components/ui/column'; +import Form from 'pl-fe/components/ui/form'; import HStack from 'pl-fe/components/ui/hstack'; import Icon from 'pl-fe/components/ui/icon'; +import Input from 'pl-fe/components/ui/input'; import Spinner from 'pl-fe/components/ui/spinner'; import Stack from 'pl-fe/components/ui/stack'; -import { useLists } from 'pl-fe/queries/accounts/use-lists'; - -import NewListForm from './components/new-list-form'; +import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; +import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; +import { useCreateList, useLists } from 'pl-fe/queries/accounts/use-lists'; import type { List as ListEntity } from 'pl-api'; const messages = defineMessages({ heading: { id: 'column.lists', defaultMessage: 'Lists' }, subheading: { id: 'lists.subheading', defaultMessage: 'Your lists' }, + label: { id: 'lists.new.title_placeholder', defaultMessage: 'New list title' }, + title: { id: 'lists.new.create', defaultMessage: 'Add list' }, + create: { id: 'lists.new.create_title', defaultMessage: 'Add list' }, }); const getOrderedLists = (lists: Array>) => { @@ -27,7 +34,54 @@ const getOrderedLists = (lists: Array>) => { return Object.values(lists).filter((item): item is ListEntity => !!item).sort((a, b) => a.title.localeCompare(b.title)); }; -const Lists: React.FC = () => { +const NewListForm: React.FC = () => { + const dispatch = useAppDispatch(); + const intl = useIntl(); + + const { title: value, isSubmitting: disabled } = useAppSelector((state) => state.listEditor); + + const { mutate: createList } = useCreateList(); + + const handleChange = (e: React.ChangeEvent) => { + dispatch(changeListEditorTitle(e.target.value)); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + createList({ title: value }); + }; + + const label = intl.formatMessage(messages.label); + const create = intl.formatMessage(messages.create); + + return ( +
+ + + + + +
+ ); +}; + +const ListsPage: React.FC = () => { const intl = useIntl(); const { data: lists } = useLists(getOrderedLists); @@ -72,4 +126,4 @@ const Lists: React.FC = () => { ); }; -export { Lists as default, getOrderedLists }; +export { ListsPage as default, NewListForm, getOrderedLists }; diff --git a/packages/pl-fe/src/features/follow-requests/components/outgoing-follow-requests.tsx b/packages/pl-fe/src/pages/account-lists/outgoing-follow-requests.tsx similarity index 90% rename from packages/pl-fe/src/features/follow-requests/components/outgoing-follow-requests.tsx rename to packages/pl-fe/src/pages/account-lists/outgoing-follow-requests.tsx index 35fb2d5ce..5bd4a0611 100644 --- a/packages/pl-fe/src/features/follow-requests/components/outgoing-follow-requests.tsx +++ b/packages/pl-fe/src/pages/account-lists/outgoing-follow-requests.tsx @@ -7,13 +7,13 @@ 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'; +import { FollowRequestsTabs } from './follow-requests'; const messages = defineMessages({ heading: { id: 'column.outgoing_follow_requests', defaultMessage: 'Outgoing follow requests' }, }); -const OutgoingFollowRequests: React.FC = () => { +const OutgoingFollowRequestsPage: React.FC = () => { const intl = useIntl(); const { data: accountIds, isLoading, hasNextPage, fetchNextPage } = useOutgoingFollowRequests(); @@ -42,4 +42,4 @@ const OutgoingFollowRequests: React.FC = () => { ); }; -export { OutgoingFollowRequests as default }; +export { OutgoingFollowRequestsPage as default };