From 4d5a8d58dc21aa5cbcadccc838c468ad98fc9daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Thu, 21 Sep 2023 23:15:07 +0200 Subject: [PATCH 1/4] Fix 'Expected "context" media feature range notation' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- src/styles/loading.scss | 2 +- src/styles/ui.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/loading.scss b/src/styles/loading.scss index 18458ba9e..56e586ae9 100644 --- a/src/styles/loading.scss +++ b/src/styles/loading.scss @@ -148,7 +148,7 @@ padding: 20px; border-radius: 10px; - @media screen and (max-width: 580px) { + @media screen and (width <= 580px) { border-radius: 0; } diff --git a/src/styles/ui.scss b/src/styles/ui.scss index 530599d3f..4191cf26c 100644 --- a/src/styles/ui.scss +++ b/src/styles/ui.scss @@ -106,7 +106,7 @@ font-family: inherit; padding: 7px 0; - @media screen and (max-width: 600px) { + @media screen and (width <= 600px) { font-size: 16px; } } From f01d088d067a4b8e93e58ee8a55e016ab1854276 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 22 Sep 2023 11:33:16 -0500 Subject: [PATCH 2/4] Remove Truth Social feed carousel --- src/actions/__tests__/suggestions.test.ts | 109 ------- src/actions/suggestions.ts | 60 +--- src/actions/timelines.ts | 34 +-- .../__tests__/feed-carousel.test.tsx | 165 ----------- src/features/feed-filtering/feed-carousel.tsx | 266 ------------------ src/features/follow-recommendations/index.tsx | 29 +- src/features/home-timeline/index.tsx | 29 +- src/features/ui/components/timeline.tsx | 5 - src/pages/home-page.tsx | 3 - src/queries/__tests__/carousels.test.ts | 44 --- src/queries/carousels.ts | 50 ---- src/queries/suggestions.ts | 51 +--- src/reducers/suggestions.ts | 12 - src/reducers/timelines.ts | 11 - src/utils/features.ts | 18 -- 15 files changed, 17 insertions(+), 869 deletions(-) delete mode 100644 src/actions/__tests__/suggestions.test.ts delete mode 100644 src/features/feed-filtering/__tests__/feed-carousel.test.tsx delete mode 100644 src/features/feed-filtering/feed-carousel.tsx delete mode 100644 src/queries/__tests__/carousels.test.ts delete mode 100644 src/queries/carousels.ts diff --git a/src/actions/__tests__/suggestions.test.ts b/src/actions/__tests__/suggestions.test.ts deleted file mode 100644 index a153208a7..000000000 --- a/src/actions/__tests__/suggestions.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { Map as ImmutableMap } from 'immutable'; - -import { __stub } from 'soapbox/api'; -import { mockStore, rootState } from 'soapbox/jest/test-helpers'; -import { normalizeInstance } from 'soapbox/normalizers'; - -import { - fetchSuggestions, -} from '../suggestions'; - -let store: ReturnType; -let state; - -describe('fetchSuggestions()', () => { - describe('with Truth Social software', () => { - beforeEach(() => { - state = rootState - .set('instance', normalizeInstance({ - version: '3.4.1 (compatible; TruthSocial 1.0.0)', - pleroma: ImmutableMap({ - metadata: ImmutableMap({ - features: [], - }), - }), - })) - .set('me', '123'); - store = mockStore(state); - }); - - describe('with a successful API request', () => { - const response = [ - { - account_id: '1', - acct: 'jl', - account_avatar: 'https://example.com/some.jpg', - display_name: 'justin', - note: '

note

', - verified: true, - }, - ]; - - beforeEach(() => { - __stub((mock) => { - mock.onGet('/api/v1/truth/carousels/suggestions').reply(200, response, { - link: '; rel=\'prev\'', - }); - }); - }); - - it('dispatches the correct actions', async() => { - const expectedActions = [ - { type: 'SUGGESTIONS_V2_FETCH_REQUEST', skipLoading: true }, - { - type: 'ACCOUNTS_IMPORT', accounts: [{ - acct: response[0].acct, - avatar: response[0].account_avatar, - avatar_static: response[0].account_avatar, - id: response[0].account_id, - note: response[0].note, - should_refetch: true, - verified: response[0].verified, - display_name: response[0].display_name, - }], - }, - { - type: 'SUGGESTIONS_TRUTH_FETCH_SUCCESS', - suggestions: response, - next: undefined, - skipLoading: true, - }, - { - type: 'RELATIONSHIPS_FETCH_REQUEST', - skipLoading: true, - ids: [response[0].account_id], - }, - ]; - await store.dispatch(fetchSuggestions()); - const actions = store.getActions(); - - expect(actions).toEqual(expectedActions); - }); - }); - - describe('with an unsuccessful API request', () => { - beforeEach(() => { - __stub((mock) => { - mock.onGet('/api/v1/truth/carousels/suggestions').networkError(); - }); - }); - - it('should dispatch the correct actions', async() => { - const expectedActions = [ - { type: 'SUGGESTIONS_V2_FETCH_REQUEST', skipLoading: true }, - { - type: 'SUGGESTIONS_V2_FETCH_FAIL', - error: new Error('Network Error'), - skipLoading: true, - skipAlert: true, - }, - ]; - - await store.dispatch(fetchSuggestions()); - const actions = store.getActions(); - - expect(actions).toEqual(expectedActions); - }); - }); - }); -}); diff --git a/src/actions/suggestions.ts b/src/actions/suggestions.ts index 600dffb7d..ae1b4aaca 100644 --- a/src/actions/suggestions.ts +++ b/src/actions/suggestions.ts @@ -1,5 +1,3 @@ -import { AxiosResponse } from 'axios'; - import { isLoggedIn } from 'soapbox/utils/auth'; import { getFeatures } from 'soapbox/utils/features'; @@ -22,10 +20,6 @@ const SUGGESTIONS_V2_FETCH_REQUEST = 'SUGGESTIONS_V2_FETCH_REQUEST'; const SUGGESTIONS_V2_FETCH_SUCCESS = 'SUGGESTIONS_V2_FETCH_SUCCESS'; const SUGGESTIONS_V2_FETCH_FAIL = 'SUGGESTIONS_V2_FETCH_FAIL'; -const SUGGESTIONS_TRUTH_FETCH_REQUEST = 'SUGGESTIONS_TRUTH_FETCH_REQUEST'; -const SUGGESTIONS_TRUTH_FETCH_SUCCESS = 'SUGGESTIONS_TRUTH_FETCH_SUCCESS'; -const SUGGESTIONS_TRUTH_FETCH_FAIL = 'SUGGESTIONS_TRUTH_FETCH_FAIL'; - const fetchSuggestionsV1 = (params: Record = {}) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch({ type: SUGGESTIONS_FETCH_REQUEST, skipLoading: true }); @@ -59,48 +53,6 @@ const fetchSuggestionsV2 = (params: Record = {}) => }); }; -export type SuggestedProfile = { - account_avatar: string - account_id: string - acct: string - display_name: string - note: string - verified: boolean -} - -const mapSuggestedProfileToAccount = (suggestedProfile: SuggestedProfile) => ({ - id: suggestedProfile.account_id, - avatar: suggestedProfile.account_avatar, - avatar_static: suggestedProfile.account_avatar, - acct: suggestedProfile.acct, - display_name: suggestedProfile.display_name, - note: suggestedProfile.note, - verified: suggestedProfile.verified, -}); - -const fetchTruthSuggestions = (params: Record = {}) => - (dispatch: AppDispatch, getState: () => RootState) => { - const next = getState().suggestions.next; - - dispatch({ type: SUGGESTIONS_V2_FETCH_REQUEST, skipLoading: true }); - - return api(getState) - .get(next ? next : '/api/v1/truth/carousels/suggestions', next ? {} : { params }) - .then((response: AxiosResponse) => { - const suggestedProfiles = response.data; - const next = getLinks(response).refs.find(link => link.rel === 'next')?.uri; - - const accounts = suggestedProfiles.map(mapSuggestedProfileToAccount); - dispatch(importFetchedAccounts(accounts, { should_refetch: true })); - dispatch({ type: SUGGESTIONS_TRUTH_FETCH_SUCCESS, suggestions: suggestedProfiles, next, skipLoading: true }); - return suggestedProfiles; - }) - .catch(error => { - dispatch({ type: SUGGESTIONS_V2_FETCH_FAIL, error, skipLoading: true, skipAlert: true }); - throw error; - }); - }; - const fetchSuggestions = (params: Record = { limit: 50 }) => (dispatch: AppDispatch, getState: () => RootState) => { const state = getState(); @@ -110,14 +62,7 @@ const fetchSuggestions = (params: Record = { limit: 50 }) => if (!me) return null; - if (features.truthSuggestions) { - return dispatch(fetchTruthSuggestions(params)) - .then((suggestions: APIEntity[]) => { - const accountIds = suggestions.map((account) => account.account_id); - dispatch(fetchRelationships(accountIds)); - }) - .catch(() => { }); - } else if (features.suggestionsV2) { + if (features.suggestionsV2) { return dispatch(fetchSuggestionsV2(params)) .then((suggestions: APIEntity[]) => { const accountIds = suggestions.map(({ account }) => account.id); @@ -161,9 +106,6 @@ export { SUGGESTIONS_V2_FETCH_REQUEST, SUGGESTIONS_V2_FETCH_SUCCESS, SUGGESTIONS_V2_FETCH_FAIL, - SUGGESTIONS_TRUTH_FETCH_REQUEST, - SUGGESTIONS_TRUTH_FETCH_SUCCESS, - SUGGESTIONS_TRUTH_FETCH_FAIL, fetchSuggestionsV1, fetchSuggestionsV2, fetchSuggestions, diff --git a/src/actions/timelines.ts b/src/actions/timelines.ts index 2e1e1710a..1de17863e 100644 --- a/src/actions/timelines.ts +++ b/src/actions/timelines.ts @@ -27,9 +27,7 @@ const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL' as const; const TIMELINE_CONNECT = 'TIMELINE_CONNECT' as const; const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT' as const; -const TIMELINE_REPLACE = 'TIMELINE_REPLACE' as const; const TIMELINE_INSERT = 'TIMELINE_INSERT' as const; -const TIMELINE_CLEAR_FEED_ACCOUNT_ID = 'TIMELINE_CLEAR_FEED_ACCOUNT_ID' as const; const MAX_QUEUED_ITEMS = 40; @@ -149,20 +147,6 @@ const parseTags = (tags: Record = {}, mode: 'any' | 'all' | 'none }); }; -const replaceHomeTimeline = ( - accountId: string | undefined, - { maxId }: Record = {}, - done?: () => void, -) => (dispatch: AppDispatch, _getState: () => RootState) => { - dispatch({ type: TIMELINE_REPLACE, accountId }); - dispatch(expandHomeTimeline({ accountId, maxId }, () => { - dispatch(insertSuggestionsIntoTimeline()); - if (done) { - done(); - } - })); -}; - const expandTimeline = (timelineId: string, path: string, params: Record = {}, done = noOp) => (dispatch: AppDispatch, getState: () => RootState) => { const timeline = getState().timelines.get(timelineId) || {} as Record; @@ -209,7 +193,6 @@ const expandTimeline = (timelineId: string, path: string, params: Record { - const endpoint = url || (accountId ? `/api/v1/accounts/${accountId}/statuses` : '/api/v1/timelines/home'); +const expandHomeTimeline = ({ url, maxId }: ExpandHomeTimelineOpts = {}, done = noOp) => { + const endpoint = url || '/api/v1/timelines/home'; const params: HomeTimelineParams = {}; if (!url && maxId) { params.max_id = maxId; } - if (accountId) { - params.exclude_replies = true; - params.with_muted = true; - } - return expandTimeline('home', endpoint, params, done); }; @@ -333,10 +311,6 @@ const insertSuggestionsIntoTimeline = () => (dispatch: AppDispatch, getState: () dispatch({ type: TIMELINE_INSERT, timeline: 'home' }); }; -const clearFeedAccountId = () => (dispatch: AppDispatch, _getState: () => RootState) => { - dispatch({ type: TIMELINE_CLEAR_FEED_ACCOUNT_ID }); -}; - // TODO: other actions type TimelineAction = TimelineDeleteAction; @@ -352,8 +326,6 @@ export { TIMELINE_EXPAND_FAIL, TIMELINE_CONNECT, TIMELINE_DISCONNECT, - TIMELINE_REPLACE, - TIMELINE_CLEAR_FEED_ACCOUNT_ID, TIMELINE_INSERT, MAX_QUEUED_ITEMS, processTimelineUpdate, @@ -363,7 +335,6 @@ export { deleteFromTimelines, clearTimeline, expandTimeline, - replaceHomeTimeline, expandHomeTimeline, expandPublicTimeline, expandRemoteTimeline, @@ -385,6 +356,5 @@ export { disconnectTimeline, scrollTopTimeline, insertSuggestionsIntoTimeline, - clearFeedAccountId, type TimelineAction, }; diff --git a/src/features/feed-filtering/__tests__/feed-carousel.test.tsx b/src/features/feed-filtering/__tests__/feed-carousel.test.tsx deleted file mode 100644 index b16f00367..000000000 --- a/src/features/feed-filtering/__tests__/feed-carousel.test.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import userEvent from '@testing-library/user-event'; -import { Map as ImmutableMap } from 'immutable'; -import React from 'react'; - -import { __stub } from 'soapbox/api'; - -import { render, screen, waitFor } from '../../../jest/test-helpers'; -import FeedCarousel from '../feed-carousel'; - -vi.mock('../../../hooks/useDimensions', () => ({ - useDimensions: () => [{ scrollWidth: 190 }, null, { width: 300 }], -})); - -(window as any).ResizeObserver = class ResizeObserver { - - observe() { } - disconnect() { } - -}; - -describe('', () => { - let store: any; - - describe('with "carousel" enabled', () => { - beforeEach(() => { - store = { - instance: { - version: '3.4.1 (compatible; TruthSocial 1.0.0)', - pleroma: ImmutableMap({ - metadata: ImmutableMap({ - features: [], - }), - }), - }, - }; - }); - - describe('with avatars', () => { - beforeEach(() => { - __stub((mock) => { - mock.onGet('/api/v1/truth/carousels/avatars') - .reply(200, [ - { account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg', seen: false }, - { account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg', seen: false }, - { account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg', seen: false }, - { account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg', seen: false }, - ]); - - mock.onGet('/api/v1/accounts/1/statuses').reply(200, [], { - link: '; rel=\'prev\'', - }); - - mock.onPost('/api/v1/truth/carousels/avatars/seen').reply(200); - }); - }); - - it('should render the Carousel', async() => { - render(, undefined, store); - - await waitFor(() => { - expect(screen.queryAllByTestId('feed-carousel')).toHaveLength(1); - expect(screen.queryAllByTestId('carousel-item')).toHaveLength(4); - }); - }); - - it('should handle the "seen" state', async() => { - render(, undefined, store); - - // Unseen - await waitFor(() => { - expect(screen.queryAllByTestId('carousel-item')).toHaveLength(4); - }); - expect(screen.getAllByTestId('carousel-item-avatar')[0]).toHaveClass('ring-accent-500'); - - // Selected - await userEvent.click(screen.getAllByTestId('carousel-item-avatar')[0]); - await waitFor(() => { - expect(screen.getAllByTestId('carousel-item-avatar')[0]).toHaveClass('ring-primary-600'); - }); - - // HACK: wait for state change - await new Promise((r) => setTimeout(r, 0)); - - // Marked as seen, not selected - await userEvent.click(screen.getAllByTestId('carousel-item-avatar')[0]); - await waitFor(() => { - expect(screen.getAllByTestId('carousel-item-avatar')[0]).toHaveClass('ring-transparent'); - }); - }); - }); - - describe('with 0 avatars', () => { - beforeEach(() => { - __stub((mock) => mock.onGet('/api/v1/truth/carousels/avatars').reply(200, [])); - }); - - it('renders nothing', async() => { - render(, undefined, store); - - await waitFor(() => { - expect(screen.queryAllByTestId('feed-carousel')).toHaveLength(0); - }); - }); - }); - - describe('with a failed request to the API', () => { - beforeEach(() => { - __stub((mock) => mock.onGet('/api/v1/truth/carousels/avatars').networkError()); - }); - - it('renders the error message', async() => { - render(, undefined, store); - - await waitFor(() => { - expect(screen.getByTestId('feed-carousel-error')).toBeInTheDocument(); - }); - }); - }); - - describe('with multiple pages of avatars', () => { - beforeEach(() => { - __stub((mock) => { - mock.onGet('/api/v1/truth/carousels/avatars') - .reply(200, [ - { account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' }, - { account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg' }, - { account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg' }, - { account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg' }, - ]); - }); - - Element.prototype.getBoundingClientRect = vi.fn(() => { - return { - width: 200, - height: 120, - x: 0, - y: 0, - toJSON: () => null, - top: 0, - left: 0, - bottom: 0, - right: 0, - }; - }); - }); - - it('should render the correct prev/next buttons', async() => { - const user = userEvent.setup(); - render(, undefined, store); - - await waitFor(() => { - expect(screen.getByTestId('prev-page')).toHaveAttribute('disabled'); - expect(screen.getByTestId('next-page')).not.toHaveAttribute('disabled'); - }); - - await user.click(screen.getByTestId('next-page')); - - await waitFor(() => { - expect(screen.getByTestId('prev-page')).not.toHaveAttribute('disabled'); - // expect(screen.getByTestId('next-page')).toHaveAttribute('disabled'); - }); - }); - }); - }); -}); diff --git a/src/features/feed-filtering/feed-carousel.tsx b/src/features/feed-filtering/feed-carousel.tsx deleted file mode 100644 index f437aad0c..000000000 --- a/src/features/feed-filtering/feed-carousel.tsx +++ /dev/null @@ -1,266 +0,0 @@ -import clsx from 'clsx'; -import React, { useEffect, useMemo, useRef, useState } from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { replaceHomeTimeline } from 'soapbox/actions/timelines'; -import { useAppDispatch, useAppSelector, useDimensions } from 'soapbox/hooks'; -import { Avatar, useCarouselAvatars, useMarkAsSeen } from 'soapbox/queries/carousels'; - -import { Card, HStack, Icon, Stack, Text } from '../../components/ui'; -import PlaceholderAvatar from '../placeholder/components/placeholder-avatar'; - -const CarouselItem = React.forwardRef(( - { avatar, seen, onViewed, onPinned }: { avatar: Avatar, seen: boolean, onViewed: (account_id: string) => void, onPinned?: (avatar: null | Avatar) => void }, - ref: React.ForwardedRef, -) => { - const dispatch = useAppDispatch(); - - const markAsSeen = useMarkAsSeen(); - - const selectedAccountId = useAppSelector(state => state.timelines.getIn(['home', 'feedAccountId']) as string); - const isSelected = avatar.account_id === selectedAccountId; - - const [isFetching, setLoading] = useState(false); - - const handleClick = () => { - if (isFetching) { - return; - } - - setLoading(true); - - if (isSelected) { - dispatch(replaceHomeTimeline(undefined, { maxId: null }, () => setLoading(false))); - - if (onPinned) { - onPinned(null); - } - } else { - if (onPinned) { - onPinned(avatar); - } - - if (!seen) { - onViewed(avatar.account_id); - markAsSeen.mutate(avatar.account_id); - } - - dispatch(replaceHomeTimeline(avatar.account_id, { maxId: null }, () => setLoading(false))); - } - }; - - return ( -
- -
- {isSelected && ( -
- -
- )} - - {avatar.acct} -
- - {avatar.acct} -
-
- ); -}); - -const FeedCarousel = () => { - const { data: avatars, isFetching, isFetched, isError } = useCarouselAvatars(); - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [_ref, setContainerRef, { width }] = useDimensions(); - const carouselItemRef = useRef(null); - - const [seenAccountIds, setSeenAccountIds] = useState([]); - const [pageSize, setPageSize] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - const [pinnedAvatar, setPinnedAvatar] = useState(null); - - const avatarsToList = useMemo(() => { - let list: (Avatar | null)[] = avatars.filter((avatar) => avatar.account_id !== pinnedAvatar?.account_id); - - // If we have an Avatar pinned, let's create a new array with "null" - // in the first position of each page. - if (pinnedAvatar) { - const index = (currentPage - 1) * pageSize; - list = [ - ...list.slice(0, index), - null, - ...list.slice(index), - ]; - } - - return list; - }, [avatars, pinnedAvatar, currentPage, pageSize]); - - const numberOfPages = Math.ceil(avatars.length / pageSize); - const widthPerAvatar = width / (Math.floor(width / 80)); - - const hasNextPage = currentPage < numberOfPages && numberOfPages > 1; - const hasPrevPage = currentPage > 1 && numberOfPages > 1; - - const handleNextPage = () => setCurrentPage((prevPage) => prevPage + 1); - const handlePrevPage = () => setCurrentPage((prevPage) => prevPage - 1); - - const markAsSeen = (account_id: string) => { - setSeenAccountIds((prev) => [...prev, account_id]); - }; - - useEffect(() => { - if (avatars.length > 0) { - setSeenAccountIds( - avatars - .filter((avatar) => avatar.seen !== false) - .map((avatar) => avatar.account_id), - ); - } - }, [avatars]); - - useEffect(() => { - if (width) { - setPageSize(Math.round(width / widthPerAvatar)); - } - }, [width, widthPerAvatar]); - - if (isError) { - return ( - - - - - - ); - } - - if (isFetched && avatars.length === 0) { - return null; - } - - return ( -
- -
- -
- -
- {pinnedAvatar ? ( -
- setPinnedAvatar(avatar)} - ref={carouselItemRef} - /> -
- ) : null} - - - {isFetching ? ( - new Array(20).fill(0).map((_, idx) => ( -
- -
- )) - ) : ( - avatarsToList.map((avatar: any, index) => ( -
- {avatar === null ? ( - -
-
-
- - ) : ( - { - setPinnedAvatar(null); - setTimeout(() => { - setPinnedAvatar(avatar); - }, 1); - }} - onViewed={markAsSeen} - /> - )} -
- )) - )} - -
- -
- -
-
-
- ); -}; - -export default FeedCarousel; diff --git a/src/features/follow-recommendations/index.tsx b/src/features/follow-recommendations/index.tsx index 0421b246a..166396c91 100644 --- a/src/features/follow-recommendations/index.tsx +++ b/src/features/follow-recommendations/index.tsx @@ -6,7 +6,7 @@ import { fetchSuggestions } from 'soapbox/actions/suggestions'; import ScrollableList from 'soapbox/components/scrollable-list'; import { Column, Stack, Text } from 'soapbox/components/ui'; import AccountContainer from 'soapbox/containers/account-container'; -import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks'; +import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; const messages = defineMessages({ heading: { id: 'followRecommendations.heading', defaultMessage: 'Suggested Profiles' }, @@ -15,7 +15,6 @@ const messages = defineMessages({ const FollowRecommendations: React.FC = () => { const dispatch = useAppDispatch(); const intl = useIntl(); - const features = useFeatures(); const suggestions = useAppSelector((state) => state.suggestions.items); const hasMore = useAppSelector((state) => !!state.suggestions.next); @@ -53,25 +52,13 @@ const FollowRecommendations: React.FC = () => { hasMore={hasMore} itemClassName='pb-4' > - {features.truthSuggestions ? ( - suggestions.map((suggestedProfile) => ( - - )) - ) : ( - suggestions.map((suggestion) => ( - - )) - )} + {suggestions.map((suggestion) => ( + + ))} diff --git a/src/features/home-timeline/index.tsx b/src/features/home-timeline/index.tsx index 7f141ad6b..a24dcbe5f 100644 --- a/src/features/home-timeline/index.tsx +++ b/src/features/home-timeline/index.tsx @@ -2,9 +2,7 @@ import React, { useEffect, useRef } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; -import { fetchRelationships } from 'soapbox/actions/accounts'; -import { fetchSuggestionsForTimeline } from 'soapbox/actions/suggestions'; -import { expandHomeTimeline, clearFeedAccountId } from 'soapbox/actions/timelines'; +import { expandHomeTimeline } from 'soapbox/actions/timelines'; import PullToRefresh from 'soapbox/components/pull-to-refresh'; import { Column, Stack, Text } from 'soapbox/components/ui'; import Timeline from 'soapbox/features/ui/components/timeline'; @@ -23,12 +21,10 @@ const HomeTimeline: React.FC = () => { const polling = useRef(null); const isPartial = useAppSelector(state => state.timelines.get('home')?.isPartial === true); - const currentAccountId = useAppSelector(state => state.timelines.get('home')?.feedAccountId as string | undefined); - const currentAccountRelationship = useAppSelector(state => currentAccountId ? state.relationships.get(currentAccountId) : null); const next = useAppSelector(state => state.timelines.get('home')?.next); const handleLoadMore = (maxId: string) => { - dispatch(expandHomeTimeline({ url: next, maxId, accountId: currentAccountId })); + dispatch(expandHomeTimeline({ url: next, maxId })); }; // Mastodon generates the feed in Redis, and can return a partial timeline @@ -51,7 +47,7 @@ const HomeTimeline: React.FC = () => { }; const handleRefresh = () => { - return dispatch(expandHomeTimeline({ accountId: currentAccountId })); + return dispatch(expandHomeTimeline()); }; useEffect(() => { @@ -62,25 +58,6 @@ const HomeTimeline: React.FC = () => { }; }, [isPartial]); - useEffect(() => { - // Check to see if we still follow the user that is selected in the Feed Carousel. - if (currentAccountId) { - dispatch(fetchRelationships([currentAccountId])); - } - }, []); - - useEffect(() => { - // If we unfollowed the currently selected user from the Feed Carousel, - // let's clear the feed filter and refetch fresh timeline data. - if (currentAccountRelationship && !currentAccountRelationship?.following) { - dispatch(clearFeedAccountId()); - - dispatch(expandHomeTimeline({}, () => { - dispatch(fetchSuggestionsForTimeline()); - })); - } - }, [currentAccountId]); - return ( diff --git a/src/features/ui/components/timeline.tsx b/src/features/ui/components/timeline.tsx index 1c17812dc..a4d7d44e6 100644 --- a/src/features/ui/components/timeline.tsx +++ b/src/features/ui/components/timeline.tsx @@ -36,13 +36,8 @@ const Timeline: React.FC = ({ const isPartial = useAppSelector(state => (state.timelines.get(timelineId)?.isPartial || false) === true); const hasMore = useAppSelector(state => state.timelines.get(timelineId)?.hasMore === true); const totalQueuedItemsCount = useAppSelector(state => state.timelines.get(timelineId)?.totalQueuedItemsCount || 0); - const isFilteringFeed = useAppSelector(state => !!state.timelines.get(timelineId)?.feedAccountId); const handleDequeueTimeline = () => { - if (isFilteringFeed) { - return; - } - dispatch(dequeueTimeline(timelineId, onLoadMore)); }; diff --git a/src/pages/home-page.tsx b/src/pages/home-page.tsx index 06a9311e2..ec33c5d5c 100644 --- a/src/pages/home-page.tsx +++ b/src/pages/home-page.tsx @@ -4,7 +4,6 @@ import { useIntl } from 'react-intl'; import { Link } from 'react-router-dom'; import { uploadCompose } from 'soapbox/actions/compose'; -import FeedCarousel from 'soapbox/features/feed-filtering/feed-carousel'; import LinkFooter from 'soapbox/features/ui/components/link-footer'; import { WhoToFollowPanel, @@ -81,8 +80,6 @@ const HomePage: React.FC = ({ children }) => { )} - {features.carousel && } - {children} {!me && ( diff --git a/src/queries/__tests__/carousels.test.ts b/src/queries/__tests__/carousels.test.ts deleted file mode 100644 index eb9501638..000000000 --- a/src/queries/__tests__/carousels.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { __stub } from 'soapbox/api'; -import { renderHook, waitFor } from 'soapbox/jest/test-helpers'; - -import { useCarouselAvatars } from '../carousels'; - -describe('useCarouselAvatars', () => { - describe('with a successful query', () => { - beforeEach(() => { - __stub((mock) => { - mock.onGet('/api/v1/truth/carousels/avatars') - .reply(200, [ - { account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' }, - { account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg' }, - { account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg' }, - { account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg' }, - ]); - }); - }); - - it('is successful', async() => { - const { result } = renderHook(() => useCarouselAvatars()); - - await waitFor(() => expect(result.current.isFetching).toBe(false)); - - expect(result.current.data?.length).toBe(4); - }); - }); - - describe('with an unsuccessful query', () => { - beforeEach(() => { - __stub((mock) => { - mock.onGet('/api/v1/truth/carousels/avatars').networkError(); - }); - }); - - it('is successful', async() => { - const { result } = renderHook(() => useCarouselAvatars()); - - await waitFor(() => expect(result.current.isFetching).toBe(false)); - - expect(result.current.error).toBeDefined(); - }); - }); -}); diff --git a/src/queries/carousels.ts b/src/queries/carousels.ts deleted file mode 100644 index d6e05798a..000000000 --- a/src/queries/carousels.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { useMutation, useQuery } from '@tanstack/react-query'; - -import { useApi, useFeatures } from 'soapbox/hooks'; - -export type Avatar = { - account_id: string - account_avatar: string - acct: string - seen?: boolean -} - -const CarouselKeys = { - avatars: ['carouselAvatars'] as const, -}; - -function useCarouselAvatars() { - const api = useApi(); - - const getCarouselAvatars = async() => { - const { data } = await api.get('/api/v1/truth/carousels/avatars'); - return data; - }; - - const result = useQuery(CarouselKeys.avatars, getCarouselAvatars, { - placeholderData: [], - keepPreviousData: true, - }); - - const avatars = result.data; - - return { - ...result, - data: avatars || [], - }; -} - -function useMarkAsSeen() { - const api = useApi(); - const features = useFeatures(); - - return useMutation(async (accountId: string) => { - if (features.carouselSeen) { - await void api.post('/api/v1/truth/carousels/avatars/seen', { - account_id: accountId, - }); - } - }); -} - -export { useCarouselAvatars, useMarkAsSeen }; \ No newline at end of file diff --git a/src/queries/suggestions.ts b/src/queries/suggestions.ts index b9455376a..dd6b90dfe 100644 --- a/src/queries/suggestions.ts +++ b/src/queries/suggestions.ts @@ -2,9 +2,8 @@ import { useInfiniteQuery, useMutation } from '@tanstack/react-query'; import { fetchRelationships } from 'soapbox/actions/accounts'; import { importFetchedAccounts } from 'soapbox/actions/importer'; -import { SuggestedProfile } from 'soapbox/actions/suggestions'; import { getLinks } from 'soapbox/api'; -import { useApi, useAppDispatch, useFeatures } from 'soapbox/hooks'; +import { useApi, useAppDispatch } from 'soapbox/hooks'; import { PaginatedResult, removePageItem } from '../utils/queries'; @@ -15,16 +14,7 @@ type Suggestion = { account: IAccount } -type TruthSuggestion = { - account_avatar: string - account_id: string - acct: string - display_name: string - note: string - verified: boolean -} - -type Result = TruthSuggestion | { +type Result = { account: string } @@ -36,20 +26,9 @@ const SuggestionKeys = { suggestions: ['suggestions'] as const, }; -const mapSuggestedProfileToAccount = (suggestedProfile: SuggestedProfile) => ({ - id: suggestedProfile.account_id, - avatar: suggestedProfile.account_avatar, - avatar_static: suggestedProfile.account_avatar, - acct: suggestedProfile.acct, - display_name: suggestedProfile.display_name, - note: suggestedProfile.note, - verified: suggestedProfile.verified, -}); - const useSuggestions = () => { const api = useApi(); const dispatch = useAppDispatch(); - const features = useFeatures(); const getV2Suggestions = async (pageParam: PageParam): Promise> => { const endpoint = pageParam?.link || '/api/v2/suggestions'; @@ -69,33 +48,9 @@ const useSuggestions = () => { }; }; - const getTruthSuggestions = async (pageParam: PageParam): Promise> => { - const endpoint = pageParam?.link || '/api/v1/truth/carousels/suggestions'; - const response = await api.get(endpoint); - const hasMore = !!response.headers.link; - const nextLink = getLinks(response).refs.find(link => link.rel === 'next')?.uri; - - const accounts = response.data.map(mapSuggestedProfileToAccount); - dispatch(importFetchedAccounts(accounts, { should_refetch: true })); - - return { - result: response.data.map((x) => ({ ...x, account: x.account_id })), - link: nextLink, - hasMore, - }; - }; - - const getSuggestions = (pageParam: PageParam) => { - if (features.truthSuggestions) { - return getTruthSuggestions(pageParam); - } else { - return getV2Suggestions(pageParam); - } - }; - const result = useInfiniteQuery( SuggestionKeys.suggestions, - ({ pageParam }: any) => getSuggestions(pageParam), + ({ pageParam }: any) => getV2Suggestions(pageParam), { keepPreviousData: true, getNextPageParam: (config) => { diff --git a/src/reducers/suggestions.ts b/src/reducers/suggestions.ts index 52fbb2a0d..8f1cc209b 100644 --- a/src/reducers/suggestions.ts +++ b/src/reducers/suggestions.ts @@ -10,8 +10,6 @@ import { SUGGESTIONS_V2_FETCH_REQUEST, SUGGESTIONS_V2_FETCH_SUCCESS, SUGGESTIONS_V2_FETCH_FAIL, - SUGGESTIONS_TRUTH_FETCH_SUCCESS, - type SuggestedProfile, } from 'soapbox/actions/suggestions'; import type { AnyAction } from 'redux'; @@ -55,14 +53,6 @@ const importSuggestions = (state: State, suggestions: APIEntities, next: string }); }; -const importTruthSuggestions = (state: State, suggestions: SuggestedProfile[], next: string | null) => { - return state.withMutations(state => { - state.update('items', items => items.concat(suggestions.map(x => ({ ...x, account: x.account_id })).map(suggestion => SuggestionRecord(suggestion)))); - state.set('isLoading', false); - state.set('next', next); - }); -}; - const dismissAccount = (state: State, accountId: string) => { return state.update('items', items => items.filterNot(item => item.account === accountId)); }; @@ -80,8 +70,6 @@ export default function suggestionsReducer(state: State = ReducerRecord(), actio return importAccounts(state, action.accounts); case SUGGESTIONS_V2_FETCH_SUCCESS: return importSuggestions(state, action.suggestions, action.next); - case SUGGESTIONS_TRUTH_FETCH_SUCCESS: - return importTruthSuggestions(state, action.suggestions, action.next); case SUGGESTIONS_FETCH_FAIL: case SUGGESTIONS_V2_FETCH_FAIL: return state.set('isLoading', false); diff --git a/src/reducers/timelines.ts b/src/reducers/timelines.ts index e71ab1471..021c02283 100644 --- a/src/reducers/timelines.ts +++ b/src/reducers/timelines.ts @@ -28,9 +28,7 @@ import { TIMELINE_DEQUEUE, MAX_QUEUED_ITEMS, TIMELINE_SCROLL_TOP, - TIMELINE_REPLACE, TIMELINE_INSERT, - TIMELINE_CLEAR_FEED_ACCOUNT_ID, } from '../actions/timelines'; import type { AnyAction } from 'redux'; @@ -49,7 +47,6 @@ const TimelineRecord = ImmutableRecord({ prev: undefined as string | undefined, items: ImmutableOrderedSet(), queuedItems: ImmutableOrderedSet(), //max= MAX_QUEUED_ITEMS - feedAccountId: null, totalQueuedItemsCount: 0, //used for queuedItems overflow for MAX_QUEUED_ITEMS+ loadingFailed: false, isPartial: false, @@ -363,12 +360,6 @@ export default function timelines(state: State = initialState, action: AnyAction return timelineConnect(state, action.timeline); case TIMELINE_DISCONNECT: return timelineDisconnect(state, action.timeline); - case TIMELINE_REPLACE: - return state - .update('home', TimelineRecord(), timeline => timeline.withMutations(timeline => { - timeline.set('items', ImmutableOrderedSet([])); - })) - .update('home', TimelineRecord(), timeline => timeline.set('feedAccountId', action.accountId)); case TIMELINE_INSERT: return state.update(action.timeline, TimelineRecord(), timeline => timeline.withMutations(timeline => { timeline.update('items', oldIds => { @@ -386,8 +377,6 @@ export default function timelines(state: State = initialState, action: AnyAction return ImmutableOrderedSet(oldIdsArray); }); })); - case TIMELINE_CLEAR_FEED_ACCOUNT_ID: - return state.update('home', TimelineRecord(), timeline => timeline.set('feedAccountId', null)); default: return state; } diff --git a/src/utils/features.ts b/src/utils/features.ts index 3d9d80795..638983cd8 100644 --- a/src/utils/features.ts +++ b/src/utils/features.ts @@ -247,19 +247,6 @@ const getInstanceFeatures = (instance: Instance) => { v.software === PLEROMA, ]), - /** - * Whether to show the Feed Carousel for suggested Statuses. - * @see GET /api/v1/truth/carousels/avatars - * @see GET /api/v1/truth/carousels/suggestions - */ - carousel: v.software === TRUTHSOCIAL, - - /** - * Ability to mark a carousel avatar as "seen." - * @see POST /api/v1/truth/carousels/avatars/seen - */ - carouselSeen: v.software === TRUTHSOCIAL, - /** * Ability to accept a chat. * POST /api/v1/pleroma/chats/:id/accept @@ -960,11 +947,6 @@ const getInstanceFeatures = (instance: Instance) => { */ truthPolicies: v.software === TRUTHSOCIAL, - /** - * Supports Truth suggestions. - */ - truthSuggestions: v.software === TRUTHSOCIAL, - /** * Whether the backend allows adding users you don't follow to lists. * @see POST /api/v1/lists/:id/accounts From f3ff33ff50a0ba0b7ea40a76049f802b6153140d Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 22 Sep 2023 11:42:28 -0500 Subject: [PATCH 3/4] Remove Trending Truths --- src/actions/trending-statuses.ts | 4 ++-- src/utils/features.ts | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/actions/trending-statuses.ts b/src/actions/trending-statuses.ts index 7ccab27ab..e22448784 100644 --- a/src/actions/trending-statuses.ts +++ b/src/actions/trending-statuses.ts @@ -17,10 +17,10 @@ const fetchTrendingStatuses = () => const instance = state.instance; const features = getFeatures(instance); - if (!features.trendingStatuses && !features.trendingTruths) return; + if (!features.trendingStatuses) return; dispatch({ type: TRENDING_STATUSES_FETCH_REQUEST }); - return api(getState).get(features.trendingTruths ? '/api/v1/truth/trending/truths' : '/api/v1/trends/statuses').then(({ data: statuses }) => { + return api(getState).get('/api/v1/trends/statuses').then(({ data: statuses }) => { dispatch(importFetchedStatuses(statuses)); dispatch({ type: TRENDING_STATUSES_FETCH_SUCCESS, statuses }); return statuses; diff --git a/src/utils/features.ts b/src/utils/features.ts index 638983cd8..b479c4611 100644 --- a/src/utils/features.ts +++ b/src/utils/features.ts @@ -923,12 +923,6 @@ const getInstanceFeatures = (instance: Instance) => { v.software === MASTODON && gte(v.compatVersion, '3.5.0'), ]), - /** - * Truth Social trending statuses API. - * @see GET /api/v1/truth/trending/truths - */ - trendingTruths: v.software === TRUTHSOCIAL, - /** * Can display trending hashtags. * @see GET /api/v1/trends From 5e204437dfb4e9df260d98e45214c6448b37915d Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 22 Sep 2023 11:46:58 -0500 Subject: [PATCH 4/4] Remove Truth Social PolicyModal --- src/components/modal-root.tsx | 11 -- src/features/ui/components/modal-root.tsx | 2 - .../ui/components/modals/policy-modal.tsx | 162 ------------------ src/features/ui/index.tsx | 12 -- src/features/ui/util/async-components.ts | 4 - src/queries/policies.ts | 47 ----- src/utils/features.ts | 7 - 7 files changed, 245 deletions(-) delete mode 100644 src/features/ui/components/modals/policy-modal.tsx delete mode 100644 src/queries/policies.ts diff --git a/src/components/modal-root.tsx b/src/components/modal-root.tsx index 5881612bf..a04f76b7a 100644 --- a/src/components/modal-root.tsx +++ b/src/components/modal-root.tsx @@ -8,8 +8,6 @@ import { cancelReplyCompose } from 'soapbox/actions/compose'; import { cancelEventCompose } from 'soapbox/actions/events'; import { openModal, closeModal } from 'soapbox/actions/modals'; import { useAppDispatch, usePrevious } from 'soapbox/hooks'; -import { queryClient } from 'soapbox/queries/client'; -import { IPolicy, PolicyKeys } from 'soapbox/queries/policies'; import type { ModalType } from 'soapbox/features/ui/components/modal-root'; import type { ReducerCompose } from 'soapbox/reducers/compose'; @@ -114,15 +112,6 @@ const ModalRoot: React.FC = ({ children, onCancel, onClose, type }) })); } else if ((hasComposeContent || hasEventComposeContent) && type === 'CONFIRM') { dispatch(closeModal('CONFIRM')); - } else if (type === 'POLICY') { - // If the user has not accepted the Policy, prevent them - // from closing the Modal. - const pendingPolicy = queryClient.getQueryData(PolicyKeys.policy) as IPolicy; - if (pendingPolicy?.pending_policy_id) { - return; - } - - onClose(); } else { onClose(); } diff --git a/src/features/ui/components/modal-root.tsx b/src/features/ui/components/modal-root.tsx index f43e2ce03..6b975fd5e 100644 --- a/src/features/ui/components/modal-root.tsx +++ b/src/features/ui/components/modal-root.tsx @@ -30,7 +30,6 @@ import { MentionsModal, MissingDescriptionModal, MuteModal, - PolicyModal, ReactionsModal, ReblogsModal, ReplyMentionsModal, @@ -75,7 +74,6 @@ const MODAL_COMPONENTS = { 'MENTIONS': MentionsModal, 'MISSING_DESCRIPTION': MissingDescriptionModal, 'MUTE': MuteModal, - 'POLICY': PolicyModal, 'REACTIONS': ReactionsModal, 'REBLOGS': ReblogsModal, 'REPLY_MENTIONS': ReplyMentionsModal, diff --git a/src/features/ui/components/modals/policy-modal.tsx b/src/features/ui/components/modals/policy-modal.tsx deleted file mode 100644 index 97cdee5bb..000000000 --- a/src/features/ui/components/modals/policy-modal.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { Text, Button, Modal, Stack, HStack } from 'soapbox/components/ui'; -import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks'; -import { usePendingPolicy, useAcceptPolicy } from 'soapbox/queries/policies'; - -interface IPolicyModal { - onClose: (type: string) => void -} - -const DirectMessageUpdates = () => { - const soapboxConfig = useSoapboxConfig(); - const { links } = soapboxConfig; - - return ( - - - - - - - - - - - - - - - - Direct Messaging - - - - - Yes, direct messages are finally here! - - - - Bring one-on-one conversations from your Feed to your DMs with - messages that automatically delete for your privacy. - - - - - - - - - - - - - - - - - Privacy Policy Updates - - -
    -
  • - - 1 - - - Consolidates previously-separate policies -
  • -
  • - - 2 - - - Reaffirms jurisdiction-specific requirements -
  • -
  • - - 3 - - - Introduces updates regarding ads and direct messages -
  • -
- - {links.get('privacyPolicy') ? ( - - View Privacy Policy - - ) : null} -
-
- ); -}; - -const supportedPolicyIds = ['1']; - -/** Modal to show privacy policy changes that need confirmation. */ -const PolicyModal: React.FC = ({ onClose }) => { - const acceptPolicy = useAcceptPolicy(); - const instance = useAppSelector((state) => state.instance); - - const { data: pendingPolicy, isLoading } = usePendingPolicy(); - - const renderPolicyBody = () => { - switch (pendingPolicy?.pending_policy_id) { - case '1': - return ; - default: - return null; - } - }; - - const handleAccept = () => { - acceptPolicy.mutate({ - policy_id: pendingPolicy?.pending_policy_id as string, - }, { - onSuccess() { - onClose('POLICY'); - }, - }); - }; - - if (isLoading || !pendingPolicy) { - return null; - } - - return ( - - - - - - - {renderPolicyBody()} - - - - - ); -}; - -export { PolicyModal as default, supportedPolicyIds }; diff --git a/src/features/ui/index.tsx b/src/features/ui/index.tsx index 179f123e2..1d53834a2 100644 --- a/src/features/ui/index.tsx +++ b/src/features/ui/index.tsx @@ -8,7 +8,6 @@ import { fetchAnnouncements } from 'soapbox/actions/announcements'; import { fetchCustomEmojis } from 'soapbox/actions/custom-emojis'; import { fetchFilters } from 'soapbox/actions/filters'; import { fetchMarker } from 'soapbox/actions/markers'; -import { openModal } from 'soapbox/actions/modals'; import { expandNotifications } from 'soapbox/actions/notifications'; import { register as registerPushNotifications } from 'soapbox/actions/push-notifications'; import { fetchScheduledStatuses } from 'soapbox/actions/scheduled-statuses'; @@ -38,13 +37,11 @@ import ProfilePage from 'soapbox/pages/profile-page'; import RemoteInstancePage from 'soapbox/pages/remote-instance-page'; import SearchPage from 'soapbox/pages/search-page'; import StatusPage from 'soapbox/pages/status-page'; -import { usePendingPolicy } from 'soapbox/queries/policies'; import { getVapidKey } from 'soapbox/utils/auth'; import { isStandalone } from 'soapbox/utils/state'; import BackgroundShapes from './components/background-shapes'; import FloatingActionButton from './components/floating-action-button'; -import { supportedPolicyIds } from './components/modals/policy-modal'; import Navbar from './components/navbar'; import BundleContainer from './containers/bundle-container'; import { @@ -389,7 +386,6 @@ interface IUI { const UI: React.FC = ({ children }) => { const history = useHistory(); const dispatch = useAppDispatch(); - const { data: pendingPolicy } = usePendingPolicy(); const node = useRef(null); const me = useAppSelector(state => state.me); const { account } = useOwnAccount(); @@ -483,14 +479,6 @@ const UI: React.FC = ({ children }) => { dispatch(registerPushNotifications()); }, [vapidKey]); - useEffect(() => { - if (account && pendingPolicy && supportedPolicyIds.includes(pendingPolicy.pending_policy_id)) { - setTimeout(() => { - dispatch(openModal('POLICY')); - }, 500); - } - }, [pendingPolicy, !!account]); - const shouldHideFAB = (): boolean => { const path = location.pathname; return Boolean(path.match(/^\/posts\/|^\/search|^\/getting-started|^\/chats/)); diff --git a/src/features/ui/util/async-components.ts b/src/features/ui/util/async-components.ts index 120617f49..3bf291c71 100644 --- a/src/features/ui/util/async-components.ts +++ b/src/features/ui/util/async-components.ts @@ -122,10 +122,6 @@ export function AccountModerationModal() { return import('../components/modals/account-moderation-modal/account-moderation-modal'); } -export function PolicyModal() { - return import('../components/modals/policy-modal'); -} - export function MediaGallery() { return import('../../../components/media-gallery'); } diff --git a/src/queries/policies.ts b/src/queries/policies.ts deleted file mode 100644 index fc91705a5..000000000 --- a/src/queries/policies.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { useMutation, useQuery } from '@tanstack/react-query'; - -import { useApi, useFeatures, useOwnAccount } from 'soapbox/hooks'; - -import { queryClient } from './client'; - -export interface IPolicy { - pending_policy_id: string -} - -const PolicyKeys = { - policy: ['policy'] as const, -}; - -function usePendingPolicy() { - const api = useApi(); - const { account } = useOwnAccount(); - const features = useFeatures(); - - const getPolicy = async() => { - const { data } = await api.get('/api/v1/truth/policies/pending'); - - return data; - }; - - return useQuery(PolicyKeys.policy, getPolicy, { - retry: 3, - refetchOnWindowFocus: true, - staleTime: 60000, // 1 minute - cacheTime: Infinity, - enabled: !!account && features.truthPolicies, - }); -} - -function useAcceptPolicy() { - const api = useApi(); - - return useMutation(( - { policy_id }: { policy_id: string }, - ) => api.patch(`/api/v1/truth/policies/${policy_id}/accept`), { - onSuccess() { - queryClient.setQueryData(PolicyKeys.policy, {}); - }, - }); -} - -export { usePendingPolicy, useAcceptPolicy, PolicyKeys }; \ No newline at end of file diff --git a/src/utils/features.ts b/src/utils/features.ts index b479c4611..2beae84e4 100644 --- a/src/utils/features.ts +++ b/src/utils/features.ts @@ -934,13 +934,6 @@ const getInstanceFeatures = (instance: Instance) => { v.software === DITTO, ]), - /** - * Truth Social policies. - * @see GET /api/v1/truth/policies/pending - * @see PATCH /api/v1/truth/policies/:policyId/accept - */ - truthPolicies: v.software === TRUTHSOCIAL, - /** * Whether the backend allows adding users you don't follow to lists. * @see POST /api/v1/lists/:id/accounts