Merge commit 'a50c8e951f' into glitch-soc/merge-upstream

This commit is contained in:
Claire 2024-07-31 18:16:01 +02:00
commit 8dd671a977
38 changed files with 313 additions and 140 deletions

View file

@ -38,10 +38,6 @@ function dispatchAssociatedRecords(
const fetchedStatuses: ApiStatusJSON[] = [];
notifications.forEach((notification) => {
if ('sample_accounts' in notification) {
fetchedAccounts.push(...notification.sample_accounts);
}
if (notification.type === 'admin.report') {
fetchedAccounts.push(notification.report.target_account);
}
@ -75,7 +71,9 @@ export const fetchNotifications = createDataLoadingThunk(
: excludeAllTypesExcept(activeFilter),
});
},
({ notifications }, { dispatch }) => {
({ notifications, accounts, statuses }, { dispatch }) => {
dispatch(importFetchedAccounts(accounts));
dispatch(importFetchedStatuses(statuses));
dispatchAssociatedRecords(dispatch, notifications);
const payload: (ApiNotificationGroupJSON | NotificationGap)[] =
notifications;
@ -95,7 +93,9 @@ export const fetchNotificationsGap = createDataLoadingThunk(
async (params: { gap: NotificationGap }) =>
apiFetchNotifications({ max_id: params.gap.maxId }),
({ notifications }, { dispatch }) => {
({ notifications, accounts, statuses }, { dispatch }) => {
dispatch(importFetchedAccounts(accounts));
dispatch(importFetchedStatuses(statuses));
dispatchAssociatedRecords(dispatch, notifications);
return { notifications };

View file

@ -1,17 +1,24 @@
import api, { apiRequest, getLinks } from 'mastodon/api';
import type { ApiNotificationGroupJSON } from 'mastodon/api_types/notifications';
import type { ApiNotificationGroupsResultJSON } from 'mastodon/api_types/notifications';
export const apiFetchNotifications = async (params?: {
exclude_types?: string[];
max_id?: string;
}) => {
const response = await api().request<ApiNotificationGroupJSON[]>({
const response = await api().request<ApiNotificationGroupsResultJSON>({
method: 'GET',
url: '/api/v2_alpha/notifications',
params,
});
return { notifications: response.data, links: getLinks(response) };
const { statuses, accounts, notification_groups } = response.data;
return {
statuses,
accounts,
notifications: notification_groups,
links: getLinks(response),
};
};
export const apiClearNotifications = () =>

View file

@ -51,7 +51,7 @@ export interface BaseNotificationGroupJSON {
group_key: string;
notifications_count: number;
type: NotificationType;
sample_accounts: ApiAccountJSON[];
sample_account_ids: string[];
latest_page_notification_at: string; // FIXME: This will only be present if the notification group is returned in a paginated list, not requested directly
most_recent_notification_id: string;
page_min_id?: string;
@ -60,7 +60,7 @@ export interface BaseNotificationGroupJSON {
interface NotificationGroupWithStatusJSON extends BaseNotificationGroupJSON {
type: NotificationWithStatusType;
status: ApiStatusJSON;
status_id: string;
}
interface NotificationWithStatusJSON extends BaseNotificationJSON {
@ -143,3 +143,9 @@ export type ApiNotificationGroupJSON =
| AccountRelationshipSeveranceNotificationGroupJSON
| NotificationGroupWithStatusJSON
| ModerationWarningNotificationGroupJSON;
export interface ApiNotificationGroupsResultJSON {
accounts: ApiAccountJSON[];
statuses: ApiStatusJSON[];
notification_groups: ApiNotificationGroupJSON[];
}

View file

@ -49,21 +49,14 @@ export const FilteredNotificationsBanner: React.FC = () => {
<span>
<FormattedMessage
id='filtered_notifications_banner.pending_requests'
defaultMessage='Notifications from {count, plural, =0 {no one} one {one person} other {# people}} you may know'
defaultMessage='From {count, plural, =0 {no one} one {one person} other {# people}} you may know'
values={{ count: policy.summary.pending_requests_count }}
/>
</span>
</div>
<div className='filtered-notifications-banner__badge'>
<div className='filtered-notifications-banner__badge__badge'>
{toCappedNumber(policy.summary.pending_notifications_count)}
</div>
<FormattedMessage
id='filtered_notifications_banner.mentions'
defaultMessage='{count, plural, one {mention} other {mentions}}'
values={{ count: policy.summary.pending_notifications_count }}
/>
{toCappedNumber(policy.summary.pending_notifications_count)}
</div>
</Link>
);

View file

@ -7,9 +7,9 @@ import { Helmet } from 'react-helmet';
import { useSelector, useDispatch } from 'react-redux';
import DeleteIcon from '@/material-icons/400-24px/delete.svg?react';
import DoneIcon from '@/material-icons/400-24px/done.svg?react';
import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react';
import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react';
import { fetchNotificationRequest, fetchNotificationsForRequest, expandNotificationsForRequest, acceptNotificationRequest, dismissNotificationRequest } from 'mastodon/actions/notifications';
import Column from 'mastodon/components/column';
import ColumnHeader from 'mastodon/components/column_header';
@ -101,7 +101,7 @@ export const NotificationRequest = ({ multiColumn, params: { id } }) => {
showBackButton
extraButton={!removed && (
<>
<IconButton className='column-header__button' iconComponent={VolumeOffIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<IconButton className='column-header__button' iconComponent={DeleteIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<IconButton className='column-header__button' iconComponent={DoneIcon} onClick={handleAccept} title={intl.formatMessage(messages.accept)} />
</>
)}

View file

@ -1,5 +1,6 @@
import { FormattedMessage } from 'react-intl';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import ReplyIcon from '@/material-icons/400-24px/reply-fill.svg?react';
import type { StatusVisibility } from 'mastodon/api_types/statuses';
import type { NotificationGroupMention } from 'mastodon/models/notification_group';
@ -39,7 +40,7 @@ export const NotificationMention: React.FC<{
return (
<NotificationWithStatus
type='mention'
icon={ReplyIcon}
icon={statusVisibility === 'direct' ? AlternateEmailIcon : ReplyIcon}
iconId='reply'
accountIds={notification.sampleAccountIds}
count={notification.notifications_count}

View file

@ -300,8 +300,7 @@
"filter_modal.select_filter.subtitle": "Use an existing category or create a new one",
"filter_modal.select_filter.title": "Filter this post",
"filter_modal.title.status": "Filter a post",
"filtered_notifications_banner.mentions": "{count, plural, one {mention} other {mentions}}",
"filtered_notifications_banner.pending_requests": "Notifications from {count, plural, =0 {no one} one {one person} other {# people}} you may know",
"filtered_notifications_banner.pending_requests": "From {count, plural, =0 {no one} one {one person} other {# people}} you may know",
"filtered_notifications_banner.title": "Filtered notifications",
"firehose.all": "All",
"firehose.local": "This server",

View file

@ -1,6 +1,6 @@
{
"about.blocks": "Moderoidut palvelimet",
"about.contact": "Ota yhteys:",
"about.contact": "Yhteydenotto:",
"about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.",
"about.domain_blocks.no_reason_available": "Syy ei ole tiedossa",
"about.domain_blocks.preamble": "Mastodonin avulla voidaan yleensä tarkastella minkä tahansa fediversumiin kuuluvan palvelimen sisältöä, ja olla yhteyksissä eri palvelinten käyttäjien kanssa. Nämä poikkeukset koskevat yksin tätä palvelinta.",
@ -45,7 +45,7 @@
"account.joined_short": "Liittynyt",
"account.languages": "Vaihda tilattuja kieliä",
"account.link_verified_on": "Linkin omistus tarkistettiin {date}",
"account.locked_info": "Tilin yksityisyystilaksi on määritetty lukittu ja tilin omistaja arvioi erikseen, kuka voi seurata häntä.",
"account.locked_info": "Tilin yksityisyystilaksi on määritetty lukittu. Tilin omistaja arvioi erikseen, kuka voi seurata häntä.",
"account.media": "Media",
"account.mention": "Mainitse @{name}",
"account.moved_to": "{name} on ilmoittanut uudeksi tilikseen",
@ -119,7 +119,7 @@
"column.blocks": "Estetyt käyttäjät",
"column.bookmarks": "Kirjanmerkit",
"column.community": "Paikallinen aikajana",
"column.direct": "Yksityiset maininnat",
"column.direct": "Yksityismaininnat",
"column.directory": "Selaa profiileja",
"column.domain_blocks": "Estetyt verkkotunnukset",
"column.favourites": "Suosikit",
@ -246,7 +246,7 @@
"emoji_button.objects": "Esineet",
"emoji_button.people": "Ihmiset",
"emoji_button.recent": "Usein käytetyt",
"emoji_button.search": "Etsi...",
"emoji_button.search": "Hae...",
"emoji_button.search_results": "Hakutulokset",
"emoji_button.symbols": "Symbolit",
"emoji_button.travel": "Matkailu ja paikat",
@ -544,13 +544,13 @@
"notifications.permission_denied": "Työpöytäilmoitukset eivät ole käytettävissä, koska selaimen käyttöoikeuspyyntö on aiemmin evätty",
"notifications.permission_denied_alert": "Työpöytäilmoituksia ei voi ottaa käyttöön, koska selaimen käyttöoikeus on aiemmin evätty",
"notifications.permission_required": "Työpöytäilmoitukset eivät ole käytettävissä, koska siihen tarvittavaa käyttöoikeutta ei ole myönnetty.",
"notifications.policy.filter_new_accounts.hint": "Luotu {days, plural, one {viime päivänä} other {viimeisenä # päivänä}}",
"notifications.policy.filter_new_accounts.hint": "Luotu {days, plural, one {viime päivän} other {viimeisen # päivän}} aikana",
"notifications.policy.filter_new_accounts_title": "Uudet tilit",
"notifications.policy.filter_not_followers_hint": "Mukaan lukien alle {days, plural, one {päivän} other {# päivää}} sinua seuranneet",
"notifications.policy.filter_not_followers_title": "Henkilöt, jotka eivät seuraa sinua",
"notifications.policy.filter_not_following_hint": "Kunnes hyväksyt ne manuaalisesti",
"notifications.policy.filter_not_following_hint": "Kunnes hyväksyt heidät manuaalisesti",
"notifications.policy.filter_not_following_title": "Henkilöt, joita et seuraa",
"notifications.policy.filter_private_mentions_hint": "Suodatetaan, ellei se vastaa omaan mainintaasi tai ellet seuraa lähettäjää",
"notifications.policy.filter_private_mentions_hint": "Suodatetaan, ellei se ole vastaus omaan mainintaasi tai ellet seuraa lähettäjää",
"notifications.policy.filter_private_mentions_title": "Ei-toivotut yksityismaininnat",
"notifications.policy.title": "Suodata ilmoitukset pois kohteesta…",
"notifications_permission_banner.enable": "Ota työpöytäilmoitukset käyttöön",
@ -573,8 +573,8 @@
"onboarding.profile.note_hint": "Voit @mainita muita käyttäjiä tai #aihetunnisteita…",
"onboarding.profile.save_and_continue": "Tallenna ja jatka",
"onboarding.profile.title": "Profiilin määritys",
"onboarding.profile.upload_avatar": "Lataa profiilikuva",
"onboarding.profile.upload_header": "Lataa profiilin otsakekuva",
"onboarding.profile.upload_avatar": "Lähetä profiilikuva",
"onboarding.profile.upload_header": "Lähetä profiilin otsakekuva",
"onboarding.share.lead": "Kerro ihmisille, kuinka he voivat löytää sinut Mastodonista!",
"onboarding.share.message": "Olen {username} #Mastodonissa! Seuraa minua osoitteessa {url}",
"onboarding.share.next_steps": "Mahdolliset seuraavat vaiheet:",
@ -614,10 +614,10 @@
"privacy.private.short": "Seuraajat",
"privacy.public.long": "Kuka tahansa Mastodonissa ja sen ulkopuolella",
"privacy.public.short": "Julkinen",
"privacy.unlisted.additional": "Tämä on muutoin kuin julkinen julkaisu, mutta sitä ei näytetä livesyöte-, aihetunniste- tai selailunäkymissä eikä Mastodon-hakutuloksissakaan, vaikka ne olisivat käyttäjätililläsi yleisesti sallittuina.",
"privacy.unlisted.additional": "Tämä toimii muuten kuin julkinen, mutta julkaisut eivät näy livesyöte-, aihetunniste- tai selausnäkymissä eivätkä Mastodonin hakutuloksissa, vaikka ne olisivat käyttäjätililläsi yleisesti sallittuina.",
"privacy.unlisted.long": "Vähemmän algoritmiperusteista sisältöä",
"privacy.unlisted.short": "Vaivihkaisesti julkinen",
"privacy_policy.last_updated": "Viimeksi päivitetty {date}",
"privacy_policy.last_updated": "Päivitetty viimeksi {date}",
"privacy_policy.title": "Tietosuojakäytäntö",
"recommended": "Suositeltu",
"refresh": "Päivitä",
@ -692,7 +692,7 @@
"search.quick_action.account_search": "Profiilit haulla {x}",
"search.quick_action.go_to_account": "Siirry profiiliin {x}",
"search.quick_action.go_to_hashtag": "Siirry aihetunnisteeseen {x}",
"search.quick_action.open_url": "Avaa verkko-osoite Mastodonissa",
"search.quick_action.open_url": "Avaa URL-osoite Mastodonissa",
"search.quick_action.status_search": "Julkaisut haulla {x}",
"search.search_or_paste": "Hae tai liitä URL-osoite",
"search_popout.full_text_search_disabled_message": "Ei saatavilla palvelimella {domain}.",
@ -800,10 +800,10 @@
"units.short.billion": "{count} mrd.",
"units.short.million": "{count} milj.",
"units.short.thousand": "{count} t.",
"upload_area.title": "Lataa raahaamalla ja pudottamalla tähän",
"upload_area.title": "Lähetä raahaamalla ja pudottamalla tähän",
"upload_button.label": "Lisää kuvia, video tai äänitiedosto",
"upload_error.limit": "Tiedostolatauksien rajoitus ylitetty.",
"upload_error.poll": "Tiedostojen lisääminen ei ole sallittua kyselyjen ohessa.",
"upload_error.limit": "Tiedostolähetysten rajoitus ylitetty.",
"upload_error.poll": "Tiedostojen lisääminen äänestysten oheen ei ole sallittua.",
"upload_form.audio_description": "Kuvaile sisältöä kuuroille ja kuulorajoitteisille",
"upload_form.description": "Kuvaile sisältöä sokeille ja näkörajoitteisille",
"upload_form.edit": "Muokkaa",
@ -819,7 +819,7 @@
"upload_modal.hint": "Napsauta tai vedä ympyrä esikatselussa valitaksesi keskipiste, joka näkyy aina pienoiskuvissa.",
"upload_modal.preparing_ocr": "Valmistellaan tekstintunnistusta…",
"upload_modal.preview_label": "Esikatselu ({ratio})",
"upload_progress.label": "Tallennetaan...",
"upload_progress.label": "Lähetetään...",
"upload_progress.processing": "Käsitellään…",
"username.taken": "Tämä käyttäjänimi on jo käytössä. Kokeile toista",
"video.close": "Sulje video",

View file

@ -1,12 +1,12 @@
{
"about.blocks": "服务器被限制",
"about.blocks": "受限服务器",
"about.contact": "联系方式:",
"about.disclaimer": "Mastodon 是自由的开源软件,商标由 Mastodon gGmbH 持有。",
"about.domain_blocks.no_reason_available": "原因不可用",
"about.domain_blocks.preamble": "通常来说,在 Mastodon 上,你可以浏览联邦宇宙中任何一台服务器上的内容,并且和上面的用户互动。但其中一些在本服务器上被设置为例外。",
"about.domain_blocks.silenced.explanation": "除非明确地搜索并关注对方,否则你不会看到来自此服务器的用户信息与内容。",
"about.domain_blocks.silenced.title": "已隐藏",
"about.domain_blocks.suspended.explanation": "此服务器的数据将不会被处理、存储或者交换,本站也将无法和来自此服务器的用户互动或者交流。",
"about.domain_blocks.silenced.title": "访问受限",
"about.domain_blocks.suspended.explanation": "不处理、存储或交换来自本服务器的任何数据,不可能与本服务器上的用户进行任何交互或通信。",
"about.domain_blocks.suspended.title": "已封禁",
"about.not_available": "此信息在当前服务器尚不可用。",
"about.powered_by": "由 {mastodon} 驱动的去中心化社交媒体",
@ -63,7 +63,7 @@
"account.requested_follow": "{name} 已经向你发送了关注请求",
"account.share": "分享 @{name} 的个人资料页",
"account.show_reblogs": "显示来自 @{name} 的转嘟",
"account.statuses_counter": "{count, plural, other {{counter} 嘟文}}",
"account.statuses_counter": "{count, plural, other {{counter} 嘟文}}",
"account.unblock": "取消屏蔽 @{name}",
"account.unblock_domain": "取消屏蔽 {domain} 域名",
"account.unblock_short": "取消屏蔽",
@ -81,7 +81,7 @@
"admin.impact_report.instance_accounts": "将要删除的账户资料",
"admin.impact_report.instance_followers": "本实例用户即将丢失的关注者",
"admin.impact_report.instance_follows": "对方实例用户将会丢失的关注者",
"admin.impact_report.title": "影响摘要",
"admin.impact_report.title": "权重一览",
"alert.rate_limited.message": "请在 {retry_time, time, medium} 后重试。",
"alert.rate_limited.title": "频率受限",
"alert.unexpected.message": "发生了意外错误。",
@ -89,14 +89,14 @@
"announcement.announcement": "公告",
"attachments_list.unprocessed": "(未处理)",
"audio.hide": "隐藏音频",
"block_modal.remote_users_caveat": "我们将要求服务器 {domain} 尊重您的决定。然而,无法保证对方一定遵从,因为某些服务器可能会以不同的方处理屏蔽操作。公开嘟文仍然可能对未登录用户可见。",
"block_modal.show_less": "显示更少",
"block_modal.show_more": "显示更多",
"block_modal.remote_users_caveat": "我们将要求服务器 {domain} 尊重您的决定。然而,我们无法保证对方一定遵从,因为某些服务器可能会以不同的方处理屏蔽操作。公开嘟文仍然可能对未登录用户可见。",
"block_modal.show_less": "隐藏",
"block_modal.show_more": "展开",
"block_modal.they_cant_mention": "他们不能提及或关注你。",
"block_modal.they_cant_see_posts": "他们看不到你的嘟文,你也看不到他们的嘟文。",
"block_modal.they_will_know": "他们可以看到他们被屏蔽。",
"block_modal.title": "屏蔽用户?",
"block_modal.you_wont_see_mentions": "你不会看到提及他们的嘟文。",
"block_modal.they_cant_see_posts": "嘟文将被设置为互相不可见。",
"block_modal.they_will_know": "他们将会获知他们被屏蔽。",
"block_modal.title": "屏蔽用户?",
"block_modal.you_wont_see_mentions": "你将无法看到提及他们的嘟文。",
"boost_modal.combo": "下次按住 {combo} 即可跳过此提示",
"bundle_column_error.copy_stacktrace": "复制错误报告",
"bundle_column_error.error.body": "请求的页面无法渲染,可能是代码出现错误或浏览器存在兼容性问题。",

View file

@ -14,7 +14,7 @@ import type { ApiReportJSON } from 'mastodon/api_types/reports';
export const NOTIFICATIONS_GROUP_MAX_AVATARS = 8;
interface BaseNotificationGroup
extends Omit<BaseNotificationGroupJSON, 'sample_accounts'> {
extends Omit<BaseNotificationGroupJSON, 'sample_account_ids'> {
sampleAccountIds: string[];
}
@ -115,8 +115,7 @@ function createAccountRelationshipSeveranceEventFromJSON(
export function createNotificationGroupFromJSON(
groupJson: ApiNotificationGroupJSON,
): NotificationGroup {
const { sample_accounts, ...group } = groupJson;
const sampleAccountIds = sample_accounts.map((account) => account.id);
const { sample_account_ids: sampleAccountIds, ...group } = groupJson;
switch (group.type) {
case 'favourite':
@ -125,9 +124,9 @@ export function createNotificationGroupFromJSON(
case 'mention':
case 'poll':
case 'update': {
const { status, ...groupWithoutStatus } = group;
const { status_id: statusId, ...groupWithoutStatus } = group;
return {
statusId: status.id,
statusId,
sampleAccountIds,
...groupWithoutStatus,
};

View file

@ -10171,25 +10171,10 @@ noscript {
}
&__badge {
display: flex;
align-items: center;
border-radius: 999px;
background: var(--background-border-color);
color: $darker-text-color;
padding: 4px;
padding-inline-end: 8px;
gap: 6px;
font-weight: 500;
font-size: 11px;
line-height: 16px;
word-break: keep-all;
&__badge {
background: $ui-button-background-color;
color: $white;
border-radius: 100px;
padding: 2px 8px;
}
background: $ui-button-background-color;
color: $white;
border-radius: 100px;
padding: 2px 8px;
}
}