Do not display account suggestion dismiss button if not supported

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak
2024-09-12 23:03:09 +02:00
parent c96a7c4dde
commit 0a7bdbb7d0
11 changed files with 24 additions and 72 deletions

View File

@ -861,7 +861,7 @@ class PlApiClient {
* Remove a suggestion
* Remove an account from follow suggestions.
*
* Requires features{@link Features['suggestions']}.
* Requires features{@link Features['suggestionsDismiss']}.
* @see {@link https://docs.joinmastodon.org/methods/suggestions/#remove}
*/
dismissSuggestions: async (accountId: string) => {

View File

@ -1085,6 +1085,14 @@ const getFeatures = (instance?: Instance) => {
features.includes('v2_suggestions'),
]),
/**
* Remove an account from follow suggestions
* @see DELETE /api/v1/suggestions/:account_id
*/
suggestionsDismiss: any([
v.software === MASTODON,
]),
/**
* Supports V2 suggested accounts.
* @see GET /api/v2/suggestions

View File

@ -1,6 +1,6 @@
{
"name": "pl-api",
"version": "0.0.28",
"version": "0.0.29",
"type": "module",
"homepage": "https://github.com/mkljczk/pl-fe/tree/fork/packages/pl-api",
"repository": {

View File

@ -134,7 +134,7 @@
"multiselect-react-dropdown": "^2.0.25",
"object-to-formdata": "^4.5.1",
"path-browserify": "^1.0.1",
"pl-api": "^0.0.28",
"pl-api": "^0.0.29",
"postcss": "^8.4.29",
"process": "^0.11.10",
"punycode": "^2.1.1",

View File

@ -1,5 +1,3 @@
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
import { fetchRelationships } from './accounts';
@ -12,8 +10,6 @@ const SUGGESTIONS_FETCH_REQUEST = 'SUGGESTIONS_FETCH_REQUEST' as const;
const SUGGESTIONS_FETCH_SUCCESS = 'SUGGESTIONS_FETCH_SUCCESS' as const;
const SUGGESTIONS_FETCH_FAIL = 'SUGGESTIONS_FETCH_FAIL' as const;
const SUGGESTIONS_DISMISS = 'SUGGESTIONS_DISMISS' as const;
const fetchSuggestions = (limit = 50) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
@ -47,24 +43,10 @@ const fetchSuggestionsForTimeline = () => (dispatch: AppDispatch) => {
dispatch(fetchSuggestions(20))?.then(() => dispatch(insertSuggestionsIntoTimeline()));
};
const dismissSuggestion = (accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
dispatch({
type: SUGGESTIONS_DISMISS,
accountId,
});
return getClient(getState).myAccount.dismissSuggestions(accountId);
};
export {
SUGGESTIONS_FETCH_REQUEST,
SUGGESTIONS_FETCH_SUCCESS,
SUGGESTIONS_FETCH_FAIL,
SUGGESTIONS_DISMISS,
fetchSuggestions,
fetchSuggestionsForTimeline,
dismissSuggestion,
};

View File

@ -1,28 +1,21 @@
import React, { useEffect } from 'react';
import React from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { fetchSuggestions } from 'pl-fe/actions/suggestions';
import ScrollableList from 'pl-fe/components/scrollable-list';
import { Column, Stack, Text } from 'pl-fe/components/ui';
import AccountContainer from 'pl-fe/containers/account-container';
import { useAppDispatch, useAppSelector } from 'pl-fe/hooks';
import { useSuggestions } from 'pl-fe/queries/suggestions';
const messages = defineMessages({
heading: { id: 'follow_recommendations.heading', defaultMessage: 'Suggested profiles' },
});
const FollowRecommendations: React.FC = () => {
const dispatch = useAppDispatch();
const intl = useIntl();
const suggestions = useAppSelector((state) => state.suggestions.items);
const isLoading = useAppSelector((state) => state.suggestions.isLoading);
const { data: suggestions, isFetching } = useSuggestions();
useEffect(() => {
dispatch(fetchSuggestions(20));
}, []);
if (suggestions.size === 0 && !isLoading) {
if (suggestions.length === 0 && !isFetching) {
return (
<Column label={intl.formatMessage(messages.heading)}>
<Text align='center'>
@ -36,7 +29,7 @@ const FollowRecommendations: React.FC = () => {
<Column label={intl.formatMessage(messages.heading)}>
<Stack space={4}>
<ScrollableList
isLoading={isLoading}
isLoading={isFetching}
scrollKey='suggestions'
itemClassName='pb-4'
>

View File

@ -5,6 +5,7 @@ import { Link } from 'react-router-dom';
import { Text, Widget } from 'pl-fe/components/ui';
import AccountContainer from 'pl-fe/containers/account-container';
import PlaceholderSidebarSuggestions from 'pl-fe/features/placeholder/components/placeholder-sidebar-suggestions';
import { useFeatures } from 'pl-fe/hooks';
import { useDismissSuggestion, useSuggestions } from 'pl-fe/queries/suggestions';
import type { Account as AccountEntity } from 'pl-fe/normalizers';
@ -18,6 +19,7 @@ interface IWhoToFollowPanel {
}
const WhoToFollowPanel = ({ limit }: IWhoToFollowPanel) => {
const features = useFeatures();
const intl = useIntl();
const { data: suggestions, isFetching } = useSuggestions();
@ -54,7 +56,7 @@ const WhoToFollowPanel = ({ limit }: IWhoToFollowPanel) => {
id={suggestion.account}
actionIcon={require('@tabler/icons/outline/x.svg')}
actionTitle={intl.formatMessage(messages.dismissSuggestion)}
onActionClick={handleDismiss}
onActionClick={features.suggestionsDismiss ? handleDismiss : undefined}
/>
))
)}

View File

@ -22,7 +22,7 @@ const useSuggestions = () => {
dispatch(importFetchedAccounts(accounts));
dispatch(fetchRelationships(accountIds));
return response.map(x => ({ ...x, account: x.account.id }));
return response.map(({ account, ...x }) => ({ ...x, account_id: account.id }));
};
const result = useQuery({

View File

@ -1,5 +1,3 @@
import { SUGGESTIONS_FETCH_SUCCESS, SUGGESTIONS_DISMISS } from 'pl-fe/actions/suggestions';
import reducer from './suggestions';
describe('suggestions reducer', () => {
@ -10,32 +8,4 @@ describe('suggestions reducer', () => {
isLoading: false,
});
});
describe('SUGGESTIONS_DISMISS', () => {
it('should remove the account', () => {
let state = reducer(undefined, {} as any);
state = reducer(state, {
type: SUGGESTIONS_FETCH_SUCCESS,
accounts: [
{ id: '123' },
{ id: '456' },
{ id: '789' },
],
});
const action = { type: SUGGESTIONS_DISMISS, id: '123' };
const expected = {
items: [
{ account: '456', source: 'past_interactions' },
{ account: '789', source: 'past_interactions' },
],
isLoading: false,
next: null,
};
expect(reducer(state, action).toJS()).toEqual(expected);
});
});
});

View File

@ -6,7 +6,6 @@ import {
SUGGESTIONS_FETCH_REQUEST,
SUGGESTIONS_FETCH_SUCCESS,
SUGGESTIONS_FETCH_FAIL,
SUGGESTIONS_DISMISS,
} from 'pl-fe/actions/suggestions';
import type { Suggestion as SuggestionEntity } from 'pl-api';
@ -46,8 +45,6 @@ const suggestionsReducer = (state: State = ReducerRecord(), action: AnyAction) =
return importSuggestions(state, action.suggestions);
case SUGGESTIONS_FETCH_FAIL:
return state.set('isLoading', false);
case SUGGESTIONS_DISMISS:
return dismissAccount(state, action.accountId);
case ACCOUNT_BLOCK_SUCCESS:
case ACCOUNT_MUTE_SUCCESS:
return dismissAccount(state, action.relationship.id);

View File

@ -8240,10 +8240,10 @@ pkg-types@^1.0.3:
mlly "^1.2.0"
pathe "^1.1.0"
pl-api@^0.0.28:
version "0.0.28"
resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.0.28.tgz#b8ad56706fa31c163e05f0610257953e76ddd720"
integrity sha512-j2j0yloxPgpQtyBehOR+aJ7LKKjwDrZLYMDg4ZojsjYi9qIS5PO9jRRpi9DSB4kFyrpQagyLbJKXY3DbeHS70w==
pl-api@^0.0.29:
version "0.0.29"
resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.0.29.tgz#59005a6051932c8b0defb552b1ecda15e1241462"
integrity sha512-NDtii+PkJ/pCJHbVx0guAPtfxcXwMYPc7Bm6517I0fJtqhuY3c+QXcaL6DXuQV+OP7+WVcdVIYqIYhhgzCMkXQ==
dependencies:
blurhash "^2.0.5"
http-link-header "^1.1.3"