refactor: lead notifications with new mail, move the tab badge in and invitation parsing to calendar

This commit is contained in:
Linus Rath
2026-10-19 17:48:57 +02:00
parent d86aa1d12b
commit 58f968a48c
33 changed files with 154 additions and 203 deletions
+12
View File
@@ -45,6 +45,7 @@ export function CalendarSettings() {
calendarDayEndHour,
calendarHideNonWorkingDays,
calendarWorkingDays,
calendarInvitationParsingEnabled,
timeFormat,
firstDayOfWeek,
updateSetting,
@@ -113,6 +114,17 @@ export function CalendarSettings() {
</SettingItem>
)}
{/* Not a notification: whether .ics attachments get calendar actions. Was under Notifications. */}
<SettingItem
label={t('invitation_parsing')}
description={t('invitation_parsing_desc')}
>
<ToggleSwitch
checked={calendarInvitationParsingEnabled}
onChange={(checked) => updateSetting('calendarInvitationParsingEnabled', checked)}
/>
</SettingItem>
<SettingItem
label={t('show_time_in_month_view')}
description={t('show_time_in_month_view_desc')}
+1 -8
View File
@@ -188,7 +188,7 @@ export function LayoutSection() {
/** The Appearance page's Sidebar section: what the folder sidebar and rail show. */
export function SidebarSection() {
const t = useTranslations('settings.appearance');
const { hideAccountSwitcher, showRailAccountList, colorfulSidebarIcons, showFolderTotalCount, faviconUnreadBadge, updateSetting } = useSettingsStore();
const { hideAccountSwitcher, showRailAccountList, colorfulSidebarIcons, showFolderTotalCount, updateSetting } = useSettingsStore();
const accounts = useAccountStore(s => s.accounts);
const multiAccount = accounts.length > 1;
@@ -227,13 +227,6 @@ export function SidebarSection() {
/>
</SettingItem>
)}
<SettingItem label={t('favicon_unread_badge.label')} description={t('favicon_unread_badge.description')}>
<ToggleSwitch
checked={faviconUnreadBadge}
onChange={(checked) => updateSetting('faviconUnreadBadge', checked)}
/>
</SettingItem>
</SettingsSection>
);
}
+107 -107
View File
@@ -45,6 +45,7 @@ type DevicesState =
export function NotificationSettings() {
const t = useTranslations('settings.notifications');
const tAppearance = useTranslations('settings.appearance');
const {
emailNotificationsEnabled,
emailNotificationSound,
@@ -52,7 +53,7 @@ export function NotificationSettings() {
pushNotifyInboxOnly,
calendarNotificationsEnabled,
calendarNotificationSound,
calendarInvitationParsingEnabled,
faviconUnreadBadge,
pushRelayUrl,
updateSetting,
} = useSettingsStore();
@@ -281,7 +282,109 @@ export function NotificationSettings() {
return (
<div className="space-y-8">
<SettingsSection title={t('push.title')} description={t('push.description')}>
<SettingsSection id="mail" title={t('email.title')} description={t('email.description')}>
{!isSettingHidden('emailNotificationsEnabled') && (
<SettingItem
label={t('email.enabled')}
description={t('email.enabled_desc')}
locked={isSettingLocked('emailNotificationsEnabled')}
>
<ToggleSwitch
checked={emailNotificationsEnabled}
onChange={(checked) => updateSetting('emailNotificationsEnabled', checked)}
/>
</SettingItem>
)}
<SettingItem
label={t('email.sound')}
description={t('email.sound_desc')}
>
<ToggleSwitch
checked={emailNotificationSound}
onChange={(checked) => updateSetting('emailNotificationSound', checked)}
disabled={!emailNotificationsEnabled}
/>
</SettingItem>
{inboxOnlyAvailable && !isSettingHidden('pushNotifyInboxOnly') && (
<SettingItem
label={t('email.inbox_only')}
description={t('email.inbox_only_desc')}
locked={isSettingLocked('pushNotifyInboxOnly')}
>
<ToggleSwitch
checked={pushNotifyInboxOnly}
onChange={(checked) => updateSetting('pushNotifyInboxOnly', checked)}
disabled={!emailNotificationsEnabled}
/>
</SettingItem>
)}
{/* The tab/app icon badge is a new-mail signal too; people look for it here. */}
<SettingItem label={tAppearance('favicon_unread_badge.label')} description={tAppearance('favicon_unread_badge.description')}>
<ToggleSwitch
checked={faviconUnreadBadge}
onChange={(checked) => updateSetting('faviconUnreadBadge', checked)}
/>
</SettingItem>
</SettingsSection>
<SettingsSection id="calendar" title={t('calendar.title')} description={t('calendar.description')}>
{!isSettingHidden('calendarNotificationsEnabled') && (
<SettingItem
label={t('calendar.enabled')}
description={t('calendar.enabled_desc')}
locked={isSettingLocked('calendarNotificationsEnabled')}
>
<ToggleSwitch
checked={calendarNotificationsEnabled}
onChange={(checked) => updateSetting('calendarNotificationsEnabled', checked)}
/>
</SettingItem>
)}
<SettingItem
label={t('calendar.sound')}
description={t('calendar.sound_desc')}
>
<ToggleSwitch
checked={calendarNotificationSound}
onChange={(checked) => updateSetting('calendarNotificationSound', checked)}
disabled={!calendarNotificationsEnabled}
/>
</SettingItem>
</SettingsSection>
<SettingsSection id="sound" title={t('sound_selection.title')} description={t('sound_selection.description')}>
<SettingItem
label={t('sound_selection.choose')}
description={t('sound_selection.choose_desc')}
>
<div className="flex items-center gap-2">
<Button
variant="ghost"
size="icon"
className="h-8 w-8"
onClick={() => playNotificationSound(notificationSoundChoice)}
title={t('test_sound')}
>
<Volume2 className="w-4 h-4" />
</Button>
<Select
value={notificationSoundChoice}
onChange={(value) => {
const choice = value as NotificationSoundChoice;
updateSetting('notificationSoundChoice', choice);
playNotificationSound(choice);
}}
options={soundOptions}
/>
</div>
</SettingItem>
</SettingsSection>
<SettingsSection id="push" title={t('push.title')} description={t('push.description')}>
<SettingItem label={t('push.enable')} description={statusDescription}>
<div className="flex items-center gap-2">
{pushEnabled && (
@@ -298,6 +401,7 @@ export function NotificationSettings() {
</SettingItem>
<SettingItem
advanced
label={t('push.relay_label')}
description={pushRelayLocked ? t('push.relay_locked_desc') : t('push.relay_desc')}
locked={pushRelayLocked}
@@ -325,7 +429,7 @@ export function NotificationSettings() {
<MultiAccountPushSettings relayBaseUrl={activeRelayUrl} />
{client && (
<SettingsSection title={t('push.devices_title')} description={t('push.devices_desc')}>
<SettingsSection id="devices" advanced title={t('push.devices_title')} description={t('push.devices_desc')}>
<div className="flex items-center justify-between gap-2">
<p className="text-xs text-muted-foreground">
{devices.kind === 'loading' && t('push.devices_loading')}
@@ -378,110 +482,6 @@ export function NotificationSettings() {
</SettingsSection>
)}
<SettingsSection title={t('sound_selection.title')} description={t('sound_selection.description')}>
<SettingItem
label={t('sound_selection.choose')}
description={t('sound_selection.choose_desc')}
>
<div className="flex items-center gap-2">
<Button
variant="ghost"
size="icon"
className="h-8 w-8"
onClick={() => playNotificationSound(notificationSoundChoice)}
title={t('test_sound')}
>
<Volume2 className="w-4 h-4" />
</Button>
<Select
value={notificationSoundChoice}
onChange={(value) => {
const choice = value as NotificationSoundChoice;
updateSetting('notificationSoundChoice', choice);
playNotificationSound(choice);
}}
options={soundOptions}
/>
</div>
</SettingItem>
</SettingsSection>
<SettingsSection title={t('email.title')} description={t('email.description')}>
{!isSettingHidden('emailNotificationsEnabled') && (
<SettingItem
label={t('email.enabled')}
description={t('email.enabled_desc')}
locked={isSettingLocked('emailNotificationsEnabled')}
>
<ToggleSwitch
checked={emailNotificationsEnabled}
onChange={(checked) => updateSetting('emailNotificationsEnabled', checked)}
/>
</SettingItem>
)}
<SettingItem
label={t('email.sound')}
description={t('email.sound_desc')}
>
<ToggleSwitch
checked={emailNotificationSound}
onChange={(checked) => updateSetting('emailNotificationSound', checked)}
disabled={!emailNotificationsEnabled}
/>
</SettingItem>
{inboxOnlyAvailable && !isSettingHidden('pushNotifyInboxOnly') && (
<SettingItem
label={t('email.inbox_only')}
description={t('email.inbox_only_desc')}
locked={isSettingLocked('pushNotifyInboxOnly')}
>
<ToggleSwitch
checked={pushNotifyInboxOnly}
onChange={(checked) => updateSetting('pushNotifyInboxOnly', checked)}
disabled={!emailNotificationsEnabled}
/>
</SettingItem>
)}
</SettingsSection>
<SettingsSection title={t('calendar.title')} description={t('calendar.description')}>
{!isSettingHidden('calendarNotificationsEnabled') && (
<SettingItem
label={t('calendar.enabled')}
description={t('calendar.enabled_desc')}
locked={isSettingLocked('calendarNotificationsEnabled')}
>
<ToggleSwitch
checked={calendarNotificationsEnabled}
onChange={(checked) => updateSetting('calendarNotificationsEnabled', checked)}
/>
</SettingItem>
)}
<SettingItem
label={t('calendar.sound')}
description={t('calendar.sound_desc')}
>
<ToggleSwitch
checked={calendarNotificationSound}
onChange={(checked) => updateSetting('calendarNotificationSound', checked)}
disabled={!calendarNotificationsEnabled}
/>
</SettingItem>
<SettingItem
label={t('calendar.invitation_parsing')}
description={t('calendar.invitation_parsing_desc')}
>
<ToggleSwitch
checked={calendarInvitationParsingEnabled}
onChange={(checked) => updateSetting('calendarInvitationParsingEnabled', checked)}
/>
</SettingItem>
</SettingsSection>
<ConfirmDialog {...confirmDialogProps} />
</div>
);
+3
View File
@@ -79,6 +79,9 @@ describe('settings search index (English messages)', () => {
expect(labels).toContain('Free scrolling');
expect(labels).toContain('Show week numbers');
expect(labels).toContain('Organize invitations as');
expect(labels).toContain('Parse email invitations');
expect(labelsFor('notifications')).toContain('Unread Count on Tab and App Icon');
expect(labelsFor('notifications')).not.toContain('Parse email invitations');
expect(labels).toContain('Contact birthday calendar');
// Option values are not settings of their own.
expect(labels).not.toContain('Disabled');
+3 -4
View File
@@ -56,7 +56,7 @@ export const tabSearchPaths: Record<Tab, string[]> = {
'settings.account.shared_accounts',
],
language: ['settings.language_region'],
notifications: ['settings.notifications'],
notifications: ['settings.notifications', 'settings.appearance.favicon_unread_badge'],
appearance: [
'settings.appearance.theme',
'settings.themes',
@@ -71,7 +71,6 @@ export const tabSearchPaths: Record<Tab, string[]> = {
'settings.appearance.show_folder_total_count',
'settings.appearance.hide_account_switcher',
'settings.appearance.show_rail_account_list',
'settings.appearance.favicon_unread_badge',
'tour.restart_title',
'tour.show_on_new_devices_title',
'settings.appearance.pro_interface',
@@ -148,7 +147,7 @@ export const archiveActionSearchPaths: ReadonlySet<string> = new Set(['settings.
export const tabKeywords: Record<Tab, string> = {
account: 'profile email user signin signout reorder rearrange drag dropdown switcher multi-account identities from address signature plus addressing unified mailbox shared group',
language: 'locale region timezone date time format',
notifications: 'sound alert push badge',
notifications: 'sound alert push badge favicon tab icon unread count background relay device',
appearance: 'theme dark light font size accent color animation density custom theme css skin toolbar sidebar account switcher icons rail layout reading pane tour',
message_list: 'inbox list preview thread conversation grouping sort order columns archive delete swipe hover favicon avatar tag color',
reading: 'mark read attachment open monospace mono font plain text images remote content block sender privacy tracking dark light',
@@ -160,7 +159,7 @@ export const tabKeywords: Record<Tab, string> = {
folders: 'mailbox subscribe',
keywords: 'tags labels colors',
security: 'password 2fa two-factor passkey app password mfa api key token phone mobile app pair qr thunderbird outlook imap client encryption pgp smime',
calendar: 'event schedule appointment meeting timezone',
calendar: 'event schedule appointment meeting timezone invitation ics tasks birthday working hours',
contacts: 'address book contact',
files: 'attachments cloud drive storage upload',
protocol_handlers: 'mailto webcal links default app protocol handler',
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "إشعارات الأحداث",
"enabled_desc": "إظهار تنبيهات لأحداث التقويم القادمة",
"sound": "صوت الإشعار",
"sound_desc": "تشغيل تنبيه صوتي لتذكيرات التقويم",
"invitation_parsing": "تحليل دعوات البريد الإلكتروني",
"invitation_parsing_desc": "اكتشاف دعوات التقويم في مرفقات البريد وإظهار إجراءات التقويم"
"sound_desc": "تشغيل تنبيه صوتي لتذكيرات التقويم"
}
},
"language_region": {
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "Notificacions d'esdeveniments",
"enabled_desc": "Mostra avisos per als esdeveniments propers del calendari",
"sound": "So de notificació",
"sound_desc": "Reprodueix un avís sonor per als recordatoris del calendari",
"invitation_parsing": "Analitza les invitacions per correu",
"invitation_parsing_desc": "Detecta les invitacions de calendari als fitxers adjunts del correu i mostra les accions del calendari"
"sound_desc": "Reprodueix un avís sonor per als recordatoris del calendari"
}
},
"language_region": {
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Oznámení o událostech",
"enabled_desc": "Zobrazovat upozornění na nadcházející události v kalendáři",
"sound": "Zvuk oznámení",
"sound_desc": "Přehrát zvukové upozornění pro připomenutí kalendáře",
"invitation_parsing": "Rozpoznávat e-mailové pozvánky",
"invitation_parsing_desc": "Rozpoznávat pozvánky kalendáře v přílohách e-mailů a zobrazovat akce kalendáře"
"sound_desc": "Přehrát zvukové upozornění pro připomenutí kalendáře"
},
"push": {
"confirm_disable_message": "Toto zařízení přestane přijímat upozornění, když je web zavřený.",
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "Begivenhedsnotifikationer",
"enabled_desc": "Vis alarmer for kommende kalenderbegivenheder",
"sound": "Notifikationslyd",
"sound_desc": "Afspil en lyd for kalenderpåmindelser",
"invitation_parsing": "Pars e-mail-invitationer",
"invitation_parsing_desc": "Registrér kalenderinvitationer i e-mail-vedhæftninger og vis kalenderhandlinger"
"sound_desc": "Afspil en lyd for kalenderpåmindelser"
}
},
"language_region": {
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Terminbenachrichtigungen",
"enabled_desc": "Erinnerungen für bevorstehende Kalendertermine anzeigen",
"sound": "Benachrichtigungston",
"sound_desc": "Einen Ton für Kalendererinnerungen abspielen",
"invitation_parsing": "E-Mail-Einladungen erkennen",
"invitation_parsing_desc": "Kalendereinladungen in E-Mail-Anhängen erkennen und Kalenderaktionen anzeigen"
"sound_desc": "Einen Ton für Kalendererinnerungen abspielen"
},
"push": {
"confirm_disable_message": "Dieses Gerät erhält keine Benachrichtigungen mehr, wenn die Seite geschlossen ist.",
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "Event notifications",
"enabled_desc": "Show alerts for upcoming calendar events",
"sound": "Notification sound",
"sound_desc": "Play an audio alert for calendar reminders",
"invitation_parsing": "Parse email invitations",
"invitation_parsing_desc": "Detect calendar invitations in email attachments and show calendar actions"
"sound_desc": "Play an audio alert for calendar reminders"
}
},
"language_region": {
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Notificaciones de eventos",
"enabled_desc": "Mostrar alertas para próximos eventos del calendario",
"sound": "Sonido de notificación",
"sound_desc": "Reproducir un sonido para recordatorios del calendario",
"invitation_parsing": "Analizar invitaciones por correo",
"invitation_parsing_desc": "Detectar invitaciones de calendario en archivos adjuntos y mostrar acciones de calendario"
"sound_desc": "Reproducir un sonido para recordatorios del calendario"
},
"push": {
"confirm_disable_message": "Este dispositivo dejará de recibir alertas cuando el sitio esté cerrado.",
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "Sündmuste teavitused",
"enabled_desc": "Kuva märguanded eelseisvate kalendrisündmuste kohta",
"sound": "Teavitusheli",
"sound_desc": "Mängi helimärguanne kalendri meeldetuletuste puhul",
"invitation_parsing": "Tuvasta e-kirjade kutsed",
"invitation_parsing_desc": "Tuvasta kalendrikutsed e-kirjade manustest ja kuva kalenditoimingud"
"sound_desc": "Mängi helimärguanne kalendri meeldetuletuste puhul"
}
},
"language_region": {
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "اعلان‌های رویداد",
"enabled_desc": "نمایش هشدار برای رویدادها",
"sound": "صدای اعلان",
"sound_desc": "پخش صدا برای یادآورها",
"invitation_parsing": "پردازش دعوت‌نامه‌های ایمیل",
"invitation_parsing_desc": "تشخیص دعوت‌نامه در پیوست ایمیل"
"sound_desc": "پخش صدا برای یادآورها"
}
},
"language_region": {
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Notifications d'événements",
"enabled_desc": "Afficher des alertes pour les événements à venir",
"sound": "Son de notification",
"sound_desc": "Jouer un son pour les rappels de calendrier",
"invitation_parsing": "Analyser les invitations par e-mail",
"invitation_parsing_desc": "Détecter les invitations de calendrier dans les pièces jointes et afficher les actions de calendrier"
"sound_desc": "Jouer un son pour les rappels de calendrier"
},
"push": {
"confirm_disable_message": "Cet appareil cessera de recevoir des alertes lorsque le site est fermé.",
+1 -3
View File
@@ -1314,9 +1314,7 @@
"enabled": "התראות על אירועים",
"enabled_desc": "הצג התראות עבור אירועי לוח שנה קרובים",
"sound": "צליל התראה",
"sound_desc": "הפעל התראה קולית עבור תזכורות יומן",
"invitation_parsing": "נתח הזמנות באימייל",
"invitation_parsing_desc": "זיהוי הזמנות ליומן בקבצים מצורפים לאימייל והצג פעולות ביומן"
"sound_desc": "הפעל התראה קולית עבור תזכורות יומן"
},
"push": {
"title": "התראות בדפדפן",
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "Esemény értesítések",
"enabled_desc": "Figyelmeztetések megjelenítése a közelgő naptári eseményekhez",
"sound": "Értesítési hang",
"sound_desc": "Hangjelzés lejátszása naptári emlékeztetőkhöz",
"invitation_parsing": "E-mail meghívók feldolgozása",
"invitation_parsing_desc": "Naptármeghívók észlelése az e-mail csatolmányokban és naptár műveletek megjelenítése"
"sound_desc": "Hangjelzés lejátszása naptári emlékeztetőkhöz"
}
},
"language_region": {
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Notifiche eventi",
"enabled_desc": "Mostra avvisi per i prossimi eventi del calendario",
"sound": "Suono di notifica",
"sound_desc": "Riproduci un suono per i promemoria del calendario",
"invitation_parsing": "Analizza inviti via e-mail",
"invitation_parsing_desc": "Rileva inviti calendario negli allegati e mostra azioni calendario"
"sound_desc": "Riproduci un suono per i promemoria del calendario"
},
"push": {
"confirm_disable_message": "Questo dispositivo non riceverà più avvisi quando il sito è chiuso.",
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "イベント通知",
"enabled_desc": "今後のカレンダーイベントのアラートを表示",
"sound": "通知音",
"sound_desc": "カレンダーリマインダーの音を鳴らす",
"invitation_parsing": "メール招待を解析",
"invitation_parsing_desc": "メール添付ファイルのカレンダー招待を検出し、カレンダーアクションを表示"
"sound_desc": "カレンダーリマインダーの音を鳴らす"
},
"push": {
"confirm_disable_message": "このデバイスは、サイトが閉じているときに通知を受信しなくなります。",
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "일정 알림",
"enabled_desc": "다가오는 일정에 대한 알림을 보여줘요",
"sound": "알림음",
"sound_desc": "일정 알림이 올 때 소리로 알려줘요",
"invitation_parsing": "이메일 초대장 분석",
"invitation_parsing_desc": "이메일 첨부파일에서 캘린더 초대장을 감지하고 캘린더에 표시해요"
"sound_desc": "일정 알림이 올 때 소리로 알려줘요"
},
"push": {
"confirm_disable_message": "이 사이트가 닫혀 있을 때 이 기기는 알림을 더 이상 받지 않습니다.",
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Pasākumu paziņojumi",
"enabled_desc": "Rādīt brīdinājumus par gaidāmajiem kalendāra pasākumiem",
"sound": "Paziņojuma skaņa",
"sound_desc": "Atskaņot skaņas signālu kalendāra atgādinājumiem",
"invitation_parsing": "Atpazīt uzaicinājumus e-pastā",
"invitation_parsing_desc": "Noteikt kalendāra uzaicinājumus pielikumos un rādīt kalendāra darbības"
"sound_desc": "Atskaņot skaņas signālu kalendāra atgādinājumiem"
},
"push": {
"confirm_disable_message": "Šī ierīce vairs nesaņems brīdinājumus, kad vietne būs aizvērta.",
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "Үйл явдлын мэдэгдэл",
"enabled_desc": "Удахгүй болох хуанлийн арга хэмжээний тухай сэрэмжлүүлэг харуулах",
"sound": "Мэдэгдэлийн дуу",
"sound_desc": "Хуанли сануулагчийн аудио дохиог тоглуулах",
"invitation_parsing": "Имэйл урилгыг задлан шинжлэх",
"invitation_parsing_desc": "Имэйл хавсралтаас хуанлийн урилгыг илрүүлж, календарийн үйлдлийг харуулах"
"sound_desc": "Хуанли сануулагчийн аудио дохиог тоглуулах"
}
},
"language_region": {
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "Hendelsesvarsler",
"enabled_desc": "Vis varsler for kommende kalenderhendelser",
"sound": "Varslingslyd",
"sound_desc": "Spill av et lydvarsel for kalenderpåminnelser",
"invitation_parsing": "Les kalenderinvitasjoner i e-post",
"invitation_parsing_desc": "Finn kalenderinvitasjoner i e-postvedlegg og vis tilgjengelige kalenderhandlinger"
"sound_desc": "Spill av et lydvarsel for kalenderpåminnelser"
}
},
"language_region": {
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Evenementmeldingen",
"enabled_desc": "Waarschuwingen tonen voor aankomende agenda-evenementen",
"sound": "Meldingsgeluid",
"sound_desc": "Een geluid afspelen voor agendaherinneringen",
"invitation_parsing": "E-mailuitnodigingen herkennen",
"invitation_parsing_desc": "Agenda-uitnodigingen in e-mailbijlagen detecteren en agendaacties tonen"
"sound_desc": "Een geluid afspelen voor agendaherinneringen"
},
"push": {
"confirm_disable_message": "Dit apparaat ontvangt geen meldingen meer als de site is gesloten.",
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Powiadomienia o wydarzeniach",
"enabled_desc": "Pokazuj alerty o nadchodzących wydarzeniach kalendarza",
"sound": "Dźwięk powiadomienia",
"sound_desc": "Odtwarzaj sygnał dźwiękowy dla przypomnień kalendarza",
"invitation_parsing": "Rozpoznawaj zaproszenia e-mail",
"invitation_parsing_desc": "Wykrywaj zaproszenia kalendarzowe w załącznikach wiadomości e-mail i pokazuj akcje kalendarza"
"sound_desc": "Odtwarzaj sygnał dźwiękowy dla przypomnień kalendarza"
},
"push": {
"confirm_disable_message": "To urządzenie przestanie otrzymywać powiadomienia, gdy strona jest zamknięta.",
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Notificações de eventos",
"enabled_desc": "Mostrar alertas para próximos eventos do calendário",
"sound": "Som de notificação",
"sound_desc": "Reproduzir um som para lembretes do calendário",
"invitation_parsing": "Analisar convites por e-mail",
"invitation_parsing_desc": "Detectar convites de calendário em anexos de e-mail e mostrar ações de calendário"
"sound_desc": "Reproduzir um som para lembretes do calendário"
},
"push": {
"confirm_disable_message": "Este dispositivo deixará de receber alertas quando o site estiver fechado.",
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "Notificări privind evenimentele",
"enabled_desc": "Afișați alerte pentru evenimentele viitoare din calendar",
"sound": "Sunet de notificare",
"sound_desc": "Redă o alertă audio pentru mementourile din calendar",
"invitation_parsing": "Analizați invitațiile prin e-mail",
"invitation_parsing_desc": "Detectați invitațiile din calendar din atașamentele de e-mail și afișați acțiunile din calendar"
"sound_desc": "Redă o alertă audio pentru mementourile din calendar"
}
},
"language_region": {
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Уведомления о событиях",
"enabled_desc": "Показывать оповещения о предстоящих событиях календаря",
"sound": "Звук уведомления",
"sound_desc": "Воспроизводить звуковой сигнал для напоминаний календаря",
"invitation_parsing": "Распознавать приглашения по почте",
"invitation_parsing_desc": "Обнаруживать приглашения календаря во вложениях писем и показывать действия календаря"
"sound_desc": "Воспроизводить звуковой сигнал для напоминаний календаря"
},
"push": {
"confirm_disable_message": "Это устройство перестанет получать оповещения, когда сайт закрыт.",
+1 -3
View File
@@ -1352,9 +1352,7 @@
"enabled": "Oznámenia o udalostiach",
"enabled_desc": "Zobrazovať upozornenia na nadchádzajúce udalosti v kalendári",
"sound": "Zvuk oznámenia",
"sound_desc": "Prehrať zvukové upozornenie pre pripomenutia kalendára",
"invitation_parsing": "Rozpoznávať e-mailové pozvánky",
"invitation_parsing_desc": "Rozpoznávať pozvánky kalendára v prílohách e-mailov a zobrazovať akcie kalendára"
"sound_desc": "Prehrať zvukové upozornenie pre pripomenutia kalendára"
},
"push": {
"title": "Oznámenia na pozadí",
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Etkinlik bildirimleri",
"enabled_desc": "Yaklaşan takvim etkinlikleri için uyarılar göster",
"sound": "Bildirim sesi",
"sound_desc": "Takvim hatırlatıcıları için sesli uyarı çal",
"invitation_parsing": "E-posta davetlerini ayrıştır",
"invitation_parsing_desc": "E-posta eklerindeki takvim davetlerini algıla ve takvim işlemlerini göster"
"sound_desc": "Takvim hatırlatıcıları için sesli uyarı çal"
},
"push": {
"confirm_disable_message": "Bu cihaz, site kapalıyken uyarı almayı durduracak.",
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "Сповіщення про події",
"enabled_desc": "Показувати сповіщення про майбутні події календаря",
"sound": "Звук сповіщення",
"sound_desc": "Відтворення звукового сповіщення для нагадувань календаря",
"invitation_parsing": "Проаналізуйте запрошення електронною поштою",
"invitation_parsing_desc": "Виявляти запрошення календаря у вкладеннях електронної пошти та показувати дії календаря"
"sound_desc": "Відтворення звукового сповіщення для нагадувань календаря"
},
"push": {
"confirm_disable_message": "Цей пристрій перестане отримувати сповіщення, коли сайт закритий.",
+1 -3
View File
@@ -1388,9 +1388,7 @@
"enabled": "活動通知",
"enabled_desc": "顯示即將開始的行事曆活動提醒",
"sound": "通知聲音",
"sound_desc": "播放行事曆提醒的音訊提醒",
"invitation_parsing": "解析郵件邀請",
"invitation_parsing_desc": "偵測郵件附件中的行事曆邀請,並顯示行事曆動作"
"sound_desc": "播放行事曆提醒的音訊提醒"
}
},
"language_region": {
+1 -3
View File
@@ -1349,9 +1349,7 @@
"enabled": "事件通知",
"enabled_desc": "显示即将发生的日历事件的提醒",
"sound": "通知声音",
"sound_desc": "播放日历提醒的音频提醒",
"invitation_parsing": "解析邮件邀请",
"invitation_parsing_desc": "检测邮件附件中的日历邀请并显示日历操作"
"sound_desc": "播放日历提醒的音频提醒"
},
"push": {
"confirm_disable_message": "当网站关闭时,此设备将停止接收提醒。",