Skip to content

Commit 4a51f74

Browse files
committed
Merge branch 'main' into temp3_for-taruntarun
# Conflicts: # config/locales/simple_form.eo.yml
2 parents 50088b9 + 865a30a commit 4a51f74

48 files changed

Lines changed: 625 additions & 147 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
2+
3+
import { apiGetFamiliarFollowers } from '../api/accounts';
4+
5+
import { importFetchedAccounts } from './importer';
6+
7+
export const fetchAccountsFamiliarFollowers = createDataLoadingThunk(
8+
'accounts_familiar_followers/fetch',
9+
({ id }: { id: string }) => apiGetFamiliarFollowers(id),
10+
([data], { dispatch }) => {
11+
if (!data) {
12+
return null;
13+
}
14+
15+
dispatch(importFetchedAccounts(data.accounts));
16+
17+
return {
18+
id: data.id,
19+
accountIds: data.accounts.map((account) => account.id),
20+
};
21+
},
22+
);

app/javascript/mastodon/api/accounts.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { apiRequestPost, apiRequestGet } from 'mastodon/api';
2-
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
2+
import type {
3+
ApiAccountJSON,
4+
ApiFamiliarFollowersJSON,
5+
} from 'mastodon/api_types/accounts';
36
import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships';
47
import type { ApiHashtagJSON } from 'mastodon/api_types/tags';
58

@@ -31,3 +34,8 @@ export const apiGetFeaturedTags = (id: string) =>
3134

3235
export const apiGetEndorsedAccounts = (id: string) =>
3336
apiRequestGet<ApiAccountJSON>(`v1/accounts/${id}/endorsements`);
37+
38+
export const apiGetFamiliarFollowers = (id: string) =>
39+
apiRequestGet<ApiFamiliarFollowersJSON>('/v1/accounts/familiar_followers', {
40+
id,
41+
});

app/javascript/mastodon/api_types/accounts.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,9 @@ export interface ApiMutedAccountJSON extends BaseApiAccountJSON {
5454
// For now, we have the same type representing both `Account` and `MutedAccount`
5555
// objects, but we should refactor this in the future.
5656
export type ApiAccountJSON = ApiMutedAccountJSON;
57+
58+
// See app/serializers/rest/familiar_followers_serializer.rb
59+
export type ApiFamiliarFollowersJSON = {
60+
id: string;
61+
accounts: ApiAccountJSON[];
62+
}[];

app/javascript/mastodon/features/notifications_v2/components/avatar_group.tsx renamed to app/javascript/mastodon/components/avatar_group.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import classNames from 'classnames';
12
import { Link } from 'react-router-dom';
23

34
import { Avatar } from 'mastodon/components/avatar';
4-
import { NOTIFICATIONS_GROUP_MAX_AVATARS } from 'mastodon/models/notification_group';
55
import { useAppSelector } from 'mastodon/store';
66

77
const AvatarWrapper: React.FC<{ accountId: string }> = ({ accountId }) => {
@@ -20,11 +20,14 @@ const AvatarWrapper: React.FC<{ accountId: string }> = ({ accountId }) => {
2020
);
2121
};
2222

23-
export const AvatarGroup: React.FC<{ accountIds: string[] }> = ({
24-
accountIds,
25-
}) => (
26-
<div className='notification-group__avatar-group'>
27-
{accountIds.slice(0, NOTIFICATIONS_GROUP_MAX_AVATARS).map((accountId) => (
23+
export const AvatarGroup: React.FC<{
24+
accountIds: string[];
25+
compact?: boolean;
26+
}> = ({ accountIds, compact = false }) => (
27+
<div
28+
className={classNames('avatar-group', { 'avatar-group--compact': compact })}
29+
>
30+
{accountIds.map((accountId) => (
2831
<AvatarWrapper key={accountId} accountId={accountId} />
2932
))}
3033
</div>

app/javascript/mastodon/features/account_timeline/components/account_header.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ import {
5959
import { getAccountHidden } from 'mastodon/selectors/accounts';
6060
import { useAppSelector, useAppDispatch } from 'mastodon/store';
6161

62+
import { FamiliarFollowers } from './familiar_followers';
6263
import { MemorialNote } from './memorial_note';
6364
import { MovedNote } from './moved_note';
6465

@@ -1022,6 +1023,7 @@ export const AccountHeader: React.FC<{
10221023
/>
10231024
</NavLink>
10241025
</div>
1026+
{signedIn && <FamiliarFollowers accountId={accountId} />}
10251027
</div>
10261028
)}
10271029
</div>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { useEffect } from 'react';
2+
3+
import { FormattedMessage } from 'react-intl';
4+
5+
import { Link } from 'react-router-dom';
6+
7+
import { fetchAccountsFamiliarFollowers } from '@/mastodon/actions/accounts_familiar_followers';
8+
import { AvatarGroup } from '@/mastodon/components/avatar_group';
9+
import type { Account } from '@/mastodon/models/account';
10+
import { getAccountFamiliarFollowers } from '@/mastodon/selectors/accounts';
11+
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
12+
13+
const AccountLink: React.FC<{ account?: Account }> = ({ account }) => (
14+
<Link to={`/@${account?.username}`} data-hover-card-account={account?.id}>
15+
{account?.display_name}
16+
</Link>
17+
);
18+
19+
const FamiliarFollowersReadout: React.FC<{ familiarFollowers: Account[] }> = ({
20+
familiarFollowers,
21+
}) => {
22+
const messageData = {
23+
name1: <AccountLink account={familiarFollowers.at(0)} />,
24+
name2: <AccountLink account={familiarFollowers.at(1)} />,
25+
othersCount: familiarFollowers.length - 2,
26+
};
27+
28+
if (familiarFollowers.length === 1) {
29+
return (
30+
<FormattedMessage
31+
id='account.familiar_followers_one'
32+
defaultMessage='Followed by {name1}'
33+
values={messageData}
34+
/>
35+
);
36+
} else if (familiarFollowers.length === 2) {
37+
return (
38+
<FormattedMessage
39+
id='account.familiar_followers_two'
40+
defaultMessage='Followed by {name1} and {name2}'
41+
values={messageData}
42+
/>
43+
);
44+
} else {
45+
return (
46+
<FormattedMessage
47+
id='account.familiar_followers_many'
48+
defaultMessage='Followed by {name1}, {name2}, and {othersCount, plural, one {# other} other {# others}}'
49+
values={messageData}
50+
/>
51+
);
52+
}
53+
};
54+
55+
export const FamiliarFollowers: React.FC<{ accountId: string }> = ({
56+
accountId,
57+
}) => {
58+
const dispatch = useAppDispatch();
59+
const familiarFollowers = useAppSelector((state) =>
60+
getAccountFamiliarFollowers(state, accountId),
61+
);
62+
63+
const hasNoData = familiarFollowers === null;
64+
65+
useEffect(() => {
66+
if (hasNoData) {
67+
void dispatch(fetchAccountsFamiliarFollowers({ id: accountId }));
68+
}
69+
}, [dispatch, accountId, hasNoData]);
70+
71+
if (hasNoData || familiarFollowers.length === 0) {
72+
return null;
73+
}
74+
75+
return (
76+
<div className='account__header__familiar-followers'>
77+
<AvatarGroup
78+
compact
79+
accountIds={familiarFollowers.slice(0, 3).map((account) => account.id)}
80+
/>
81+
<FamiliarFollowersReadout familiarFollowers={familiarFollowers} />
82+
</div>
83+
);
84+
};

app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import { HotKeys } from 'react-hotkeys';
77

88
import { replyComposeById } from 'mastodon/actions/compose';
99
import { navigateToStatus } from 'mastodon/actions/statuses';
10+
import { AvatarGroup } from 'mastodon/components/avatar_group';
1011
import type { IconProp } from 'mastodon/components/icon';
1112
import { Icon } from 'mastodon/components/icon';
1213
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
14+
import { NOTIFICATIONS_GROUP_MAX_AVATARS } from 'mastodon/models/notification_group';
1315
import { useAppSelector, useAppDispatch } from 'mastodon/store';
1416

15-
import { AvatarGroup } from './avatar_group';
1617
import { DisplayedName } from './displayed_name';
1718
import { EmbeddedStatus } from './embedded_status';
1819

@@ -98,7 +99,12 @@ export const NotificationGroupWithStatus: React.FC<{
9899
<div className='notification-group__main'>
99100
<div className='notification-group__main__header'>
100101
<div className='notification-group__main__header__wrapper'>
101-
<AvatarGroup accountIds={accountIds} />
102+
<AvatarGroup
103+
accountIds={accountIds.slice(
104+
0,
105+
NOTIFICATIONS_GROUP_MAX_AVATARS,
106+
)}
107+
/>
102108

103109
{actions && (
104110
<div className='notification-group__actions'>{actions}</div>

app/javascript/mastodon/locales/bg.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
"account.copy": "Копиране на връзка към профила",
2525
"account.direct": "Частно споменаване на @{name}",
2626
"account.disable_notifications": "Спиране на известяване при публикуване от @{name}",
27+
"account.domain_blocking": "Блокиране на домейн",
2728
"account.edit_profile": "Редактиране на профила",
2829
"account.enable_notifications": "Известяване при публикуване от @{name}",
2930
"account.endorse": "Представи в профила",
3031
"account.featured": "Препоръчано",
32+
"account.featured.accounts": "Профили",
3133
"account.featured.hashtags": "Хаштагове",
3234
"account.featured.posts": "Публикации",
3335
"account.featured_tags.last_status_at": "Последна публикация на {date}",
@@ -40,6 +42,7 @@
4042
"account.following": "Последвано",
4143
"account.following_counter": "{count, plural, one {{counter} последван} other {{counter} последвани}}",
4244
"account.follows.empty": "Потребителят още никого не следва.",
45+
"account.follows_you": "Следва ви",
4346
"account.go_to_profile": "Към профила",
4447
"account.hide_reblogs": "Скриване на подсилвания от @{name}",
4548
"account.in_memoriam": "В памет на.",
@@ -54,13 +57,17 @@
5457
"account.mute_notifications_short": "Заглушаване на известията",
5558
"account.mute_short": "Заглушаване",
5659
"account.muted": "Заглушено",
60+
"account.muting": "Заглушаване",
61+
"account.mutual": "Взаимно се следвате",
5762
"account.no_bio": "Няма представен опис.",
5863
"account.open_original_page": "Отваряне на първообразната страница",
5964
"account.posts": "Публикации",
6065
"account.posts_with_replies": "Публ. и отговори",
66+
"account.remove_from_followers": "Премахване на {name} от последователи",
6167
"account.report": "Докладване на @{name}",
6268
"account.requested": "Чака се одобрение. Щракнете за отмяна на заявката за последване",
6369
"account.requested_follow": "{name} поиска да ви последва",
70+
"account.requests_to_follow_you": "Заявки да ви последват",
6471
"account.share": "Споделяне на профила на @{name}",
6572
"account.show_reblogs": "Показване на подсилвания от @{name}",
6673
"account.statuses_counter": "{count, plural, one {{counter} публикация} other {{counter} публикации}}",
@@ -227,6 +234,9 @@
227234
"confirmations.redraft.confirm": "Изтриване и преработване",
228235
"confirmations.redraft.message": "Наистина ли искате да изтриете тази публикация и да я направите чернова? Означаванията като любими и подсилванията ще се изгубят, а и отговорите към първоначалната публикация ще осиротеят.",
229236
"confirmations.redraft.title": "Изтривате и преработвате ли публикацията?",
237+
"confirmations.remove_from_followers.confirm": "Премахване на последовател",
238+
"confirmations.remove_from_followers.message": "{name} ще спре да ви следва. Наистина ли искате да продължите?",
239+
"confirmations.remove_from_followers.title": "Премахвате ли последовател?",
230240
"confirmations.reply.confirm": "Отговор",
231241
"confirmations.reply.message": "Отговарянето сега ще замени съобщението, което в момента съставяте. Сигурни ли сте, че искате да продължите?",
232242
"confirmations.reply.title": "Презаписвате ли публикацията?",

app/javascript/mastodon/locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
"account.edit_profile": "Edit profile",
2929
"account.enable_notifications": "Notify me when @{name} posts",
3030
"account.endorse": "Feature on profile",
31+
"account.familiar_followers_many": "Followed by {name1}, {name2}, and {othersCount, plural, one {# other} other {# others}}",
32+
"account.familiar_followers_one": "Followed by {name1}",
33+
"account.familiar_followers_two": "Followed by {name1} and {name2}",
3134
"account.featured": "Featured",
3235
"account.featured.accounts": "Profiles",
3336
"account.featured.hashtags": "Hashtags",

0 commit comments

Comments
 (0)