mirror of
https://github.com/mastodon/mastodon.git
synced 2025-05-07 12:16:14 +00:00
Add ability to feature and unfeature hashtags from web UI (#34490)
This commit is contained in:
parent
926c67c648
commit
40157e063d
|
@ -1,4 +1,10 @@
|
||||||
import { apiGetTag, apiFollowTag, apiUnfollowTag } from 'mastodon/api/tags';
|
import {
|
||||||
|
apiGetTag,
|
||||||
|
apiFollowTag,
|
||||||
|
apiUnfollowTag,
|
||||||
|
apiFeatureTag,
|
||||||
|
apiUnfeatureTag,
|
||||||
|
} from 'mastodon/api/tags';
|
||||||
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
||||||
|
|
||||||
export const fetchHashtag = createDataLoadingThunk(
|
export const fetchHashtag = createDataLoadingThunk(
|
||||||
|
@ -15,3 +21,13 @@ export const unfollowHashtag = createDataLoadingThunk(
|
||||||
'tags/unfollow',
|
'tags/unfollow',
|
||||||
({ tagId }: { tagId: string }) => apiUnfollowTag(tagId),
|
({ tagId }: { tagId: string }) => apiUnfollowTag(tagId),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const featureHashtag = createDataLoadingThunk(
|
||||||
|
'tags/feature',
|
||||||
|
({ tagId }: { tagId: string }) => apiFeatureTag(tagId),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const unfeatureHashtag = createDataLoadingThunk(
|
||||||
|
'tags/unfeature',
|
||||||
|
({ tagId }: { tagId: string }) => apiUnfeatureTag(tagId),
|
||||||
|
);
|
||||||
|
|
|
@ -10,6 +10,12 @@ export const apiFollowTag = (tagId: string) =>
|
||||||
export const apiUnfollowTag = (tagId: string) =>
|
export const apiUnfollowTag = (tagId: string) =>
|
||||||
apiRequestPost<ApiHashtagJSON>(`v1/tags/${tagId}/unfollow`);
|
apiRequestPost<ApiHashtagJSON>(`v1/tags/${tagId}/unfollow`);
|
||||||
|
|
||||||
|
export const apiFeatureTag = (tagId: string) =>
|
||||||
|
apiRequestPost<ApiHashtagJSON>(`v1/tags/${tagId}/feature`);
|
||||||
|
|
||||||
|
export const apiUnfeatureTag = (tagId: string) =>
|
||||||
|
apiRequestPost<ApiHashtagJSON>(`v1/tags/${tagId}/unfeature`);
|
||||||
|
|
||||||
export const apiGetFollowedTags = async (url?: string) => {
|
export const apiGetFollowedTags = async (url?: string) => {
|
||||||
const response = await api().request<ApiHashtagJSON[]>({
|
const response = await api().request<ApiHashtagJSON[]>({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
|
@ -10,4 +10,5 @@ export interface ApiHashtagJSON {
|
||||||
url: string;
|
url: string;
|
||||||
history: [ApiHistoryJSON, ...ApiHistoryJSON[]];
|
history: [ApiHistoryJSON, ...ApiHistoryJSON[]];
|
||||||
following?: boolean;
|
following?: boolean;
|
||||||
|
featuring?: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
fetchHashtag,
|
fetchHashtag,
|
||||||
followHashtag,
|
followHashtag,
|
||||||
unfollowHashtag,
|
unfollowHashtag,
|
||||||
|
featureHashtag,
|
||||||
|
unfeatureHashtag,
|
||||||
} from 'mastodon/actions/tags_typed';
|
} from 'mastodon/actions/tags_typed';
|
||||||
import type { ApiHashtagJSON } from 'mastodon/api_types/tags';
|
import type { ApiHashtagJSON } from 'mastodon/api_types/tags';
|
||||||
import { Button } from 'mastodon/components/button';
|
import { Button } from 'mastodon/components/button';
|
||||||
|
@ -28,6 +30,11 @@ const messages = defineMessages({
|
||||||
id: 'hashtag.admin_moderation',
|
id: 'hashtag.admin_moderation',
|
||||||
defaultMessage: 'Open moderation interface for #{name}',
|
defaultMessage: 'Open moderation interface for #{name}',
|
||||||
},
|
},
|
||||||
|
feature: { id: 'hashtag.feature', defaultMessage: 'Feature on profile' },
|
||||||
|
unfeature: {
|
||||||
|
id: 'hashtag.unfeature',
|
||||||
|
defaultMessage: "Don't feature on profile",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const usesRenderer = (displayNumber: React.ReactNode, pluralReady: number) => (
|
const usesRenderer = (displayNumber: React.ReactNode, pluralReady: number) => (
|
||||||
|
@ -88,22 +95,51 @@ export const HashtagHeader: React.FC<{
|
||||||
}, [dispatch, tagId, setTag]);
|
}, [dispatch, tagId, setTag]);
|
||||||
|
|
||||||
const menu = useMemo(() => {
|
const menu = useMemo(() => {
|
||||||
const tmp = [];
|
const arr = [];
|
||||||
|
|
||||||
if (
|
if (tag && signedIn) {
|
||||||
tag &&
|
const handleFeature = () => {
|
||||||
signedIn &&
|
if (tag.featuring) {
|
||||||
(permissions & PERMISSION_MANAGE_TAXONOMIES) ===
|
void dispatch(unfeatureHashtag({ tagId })).then((result) => {
|
||||||
PERMISSION_MANAGE_TAXONOMIES
|
if (isFulfilled(result)) {
|
||||||
) {
|
setTag(result.payload);
|
||||||
tmp.push({
|
}
|
||||||
text: intl.formatMessage(messages.adminModeration, { name: tag.id }),
|
|
||||||
href: `/admin/tags/${tag.id}`,
|
return '';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
void dispatch(featureHashtag({ tagId })).then((result) => {
|
||||||
|
if (isFulfilled(result)) {
|
||||||
|
setTag(result.payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
arr.push({
|
||||||
|
text: intl.formatMessage(
|
||||||
|
tag.featuring ? messages.unfeature : messages.feature,
|
||||||
|
),
|
||||||
|
action: handleFeature,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
arr.push(null);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(permissions & PERMISSION_MANAGE_TAXONOMIES) ===
|
||||||
|
PERMISSION_MANAGE_TAXONOMIES
|
||||||
|
) {
|
||||||
|
arr.push({
|
||||||
|
text: intl.formatMessage(messages.adminModeration, { name: tagId }),
|
||||||
|
href: `/admin/tags/${tag.id}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmp;
|
return arr;
|
||||||
}, [signedIn, permissions, intl, tag]);
|
}, [setTag, dispatch, tagId, signedIn, permissions, intl, tag]);
|
||||||
|
|
||||||
const handleFollow = useCallback(() => {
|
const handleFollow = useCallback(() => {
|
||||||
if (!signedIn || !tag) {
|
if (!signedIn || !tag) {
|
||||||
|
|
|
@ -405,8 +405,10 @@
|
||||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participant} other {{counter} participants}}",
|
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participant} other {{counter} participants}}",
|
||||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} post} other {{counter} posts}}",
|
"hashtag.counter_by_uses": "{count, plural, one {{counter} post} other {{counter} posts}}",
|
||||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} post} other {{counter} posts}} today",
|
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} post} other {{counter} posts}} today",
|
||||||
|
"hashtag.feature": "Feature on profile",
|
||||||
"hashtag.follow": "Follow hashtag",
|
"hashtag.follow": "Follow hashtag",
|
||||||
"hashtag.mute": "Mute #{hashtag}",
|
"hashtag.mute": "Mute #{hashtag}",
|
||||||
|
"hashtag.unfeature": "Don't feature on profile",
|
||||||
"hashtag.unfollow": "Unfollow hashtag",
|
"hashtag.unfollow": "Unfollow hashtag",
|
||||||
"hashtags.and_other": "…and {count, plural, other {# more}}",
|
"hashtags.and_other": "…and {count, plural, other {# more}}",
|
||||||
"hints.profiles.followers_may_be_missing": "Followers for this profile may be missing.",
|
"hints.profiles.followers_may_be_missing": "Followers for this profile may be missing.",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user