mirror of
https://github.com/mastodon/mastodon.git
synced 2026-09-28 08:17:53 -05:00
Redesign: Add follow requests indicator to notifications page (#40683)
This commit is contained in:
@@ -2,6 +2,8 @@ import { useCallback, useEffect } from 'react';
|
||||
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import type { Map as ImmutableMap } from 'immutable';
|
||||
|
||||
import {
|
||||
PenNibIcon,
|
||||
HouseIcon,
|
||||
@@ -14,6 +16,7 @@ import {
|
||||
} from '@phosphor-icons/react';
|
||||
|
||||
import FediIcon from '@/images/icons/icon_fediverse.svg?react';
|
||||
import { fetchFollowRequests } from '@/mastodon/actions/accounts';
|
||||
import { fetchLists } from '@/mastodon/actions/lists';
|
||||
import { closeNavigation } from '@/mastodon/actions/navigation';
|
||||
import { fetchFollowedHashtags } from '@/mastodon/actions/tags_typed';
|
||||
@@ -78,13 +81,39 @@ function useFollowedHashtags() {
|
||||
return { followedHashtags: tags };
|
||||
}
|
||||
|
||||
export function useFollowRequestsCount({
|
||||
fetch = true,
|
||||
}: { fetch?: boolean } = {}) {
|
||||
const followRequestsCount = useAppSelector(
|
||||
(state) =>
|
||||
(
|
||||
state.user_lists.getIn(['follow_requests', 'items']) as
|
||||
| ImmutableMap<string, unknown>
|
||||
| undefined
|
||||
)?.size ?? 0,
|
||||
);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
if (fetch) {
|
||||
dispatch(fetchFollowRequests());
|
||||
}
|
||||
}, [dispatch, fetch]);
|
||||
|
||||
return followRequestsCount;
|
||||
}
|
||||
|
||||
export function useNotificationsCount() {
|
||||
const unreadNotificationsCount = useAppSelector(
|
||||
selectUnreadNotificationGroupsCount,
|
||||
);
|
||||
const followRequestsCount = useFollowRequestsCount();
|
||||
|
||||
const { unreadAnnouncementCount } = useHasAnnouncements();
|
||||
|
||||
return unreadNotificationsCount + unreadAnnouncementCount;
|
||||
return (
|
||||
unreadNotificationsCount + followRequestsCount + unreadAnnouncementCount
|
||||
);
|
||||
}
|
||||
|
||||
const isFediverseFeedsLinkActive = (
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { UserPlusIcon } from '@phosphor-icons/react';
|
||||
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
|
||||
import { useFollowRequestsCount } from '../../navigation_panel/redesign';
|
||||
|
||||
/**
|
||||
* This banner is only shown to users whose notification policy filters
|
||||
* or blocks notifications from accounts that are not following them,
|
||||
* so that they have a way of finding out about pending requests.
|
||||
*/
|
||||
export const FollowRequestsBanner: React.FC = () => {
|
||||
const followRequestsCount = useFollowRequestsCount({ fetch: false });
|
||||
|
||||
if (followRequestsCount === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Link className='filtered-notifications-banner' to='/follow_requests'>
|
||||
<div className='notification-group__icon'>
|
||||
<Icon icon={UserPlusIcon} id='filtered-notifications' />
|
||||
</div>
|
||||
|
||||
<div className='filtered-notifications-banner__text'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='column.follow_requests'
|
||||
defaultMessage='Follow requests'
|
||||
/>
|
||||
</strong>
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='follow_requests.pending_requests'
|
||||
defaultMessage='From {count, plural, =0 {no one} one {one person} other {# people}} you may know'
|
||||
values={{ count: followRequestsCount }}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
@@ -61,6 +61,7 @@ import {
|
||||
import NotificationsPermissionBanner from '../notifications/components/notifications_permission_banner';
|
||||
import ColumnSettingsContainer from '../notifications/containers/column_settings_container';
|
||||
|
||||
import { FollowRequestsBanner } from './components/follow_requests_banner';
|
||||
import { NotificationGroup } from './components/notification_group';
|
||||
import { FilterBar } from './filter_bar';
|
||||
|
||||
@@ -229,6 +230,7 @@ export const Notifications: React.FC<{
|
||||
{needsNotificationPermission && <NotificationsPermissionBanner />}
|
||||
{shouldShowAnnouncements && <Announcements />}
|
||||
<FilteredNotificationsBanner />
|
||||
<FollowRequestsBanner />
|
||||
</>
|
||||
);
|
||||
|
||||
|
||||
@@ -840,6 +840,7 @@
|
||||
"firehose.remote": "Other servers",
|
||||
"follow_request.authorize": "Authorize",
|
||||
"follow_request.reject": "Reject",
|
||||
"follow_requests.pending_requests": "From {count, plural, =0 {no one} one {one person} other {# people}} you may know",
|
||||
"follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
|
||||
"follow_suggestions.curated_suggestion": "Staff pick",
|
||||
"follow_suggestions.dismiss": "Don't show again",
|
||||
|
||||
@@ -5,6 +5,8 @@ import type { NotificationGroup } from 'mastodon/models/notification_group';
|
||||
import type { NotificationGap } from 'mastodon/reducers/notification_groups';
|
||||
import type { RootState } from 'mastodon/store';
|
||||
|
||||
import { isRedesignEnabled } from '../utils/environment';
|
||||
|
||||
import {
|
||||
selectSettingsNotificationsExcludedTypes,
|
||||
selectSettingsNotificationsQuickFilterActive,
|
||||
@@ -63,19 +65,23 @@ export const selectUnreadNotificationGroupsCount = createSelector(
|
||||
selectPendingNotificationGroups,
|
||||
],
|
||||
(notificationMarker, groups, pendingGroups) => {
|
||||
function filterRelevantNotifications(
|
||||
group: NotificationGap | NotificationGroup,
|
||||
) {
|
||||
if (isRedesignEnabled() && group.type === 'follow_request') {
|
||||
// Pending follow requests are counted separately in the redesign
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
group.type !== 'gap' &&
|
||||
group.page_max_id &&
|
||||
compareId(group.page_max_id, notificationMarker) > 0
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
groups.filter(
|
||||
(group) =>
|
||||
group.type !== 'gap' &&
|
||||
group.page_max_id &&
|
||||
compareId(group.page_max_id, notificationMarker) > 0,
|
||||
).length +
|
||||
pendingGroups.filter(
|
||||
(group) =>
|
||||
group.type !== 'gap' &&
|
||||
group.page_max_id &&
|
||||
compareId(group.page_max_id, notificationMarker) > 0,
|
||||
).length
|
||||
groups.filter(filterRelevantNotifications).length +
|
||||
pendingGroups.filter(filterRelevantNotifications).length
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user