diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.jsx b/app/javascript/mastodon/features/notifications/components/column_settings.jsx
index e0d4e6ff73b..cd9f4f18f68 100644
--- a/app/javascript/mastodon/features/notifications/components/column_settings.jsx
+++ b/app/javascript/mastodon/features/notifications/components/column_settings.jsx
@@ -13,7 +13,7 @@ import GrantPermissionButton from './grant_permission_button';
import { PolicyControls } from './policy_controls';
import SettingToggle from './setting_toggle';
import { ColumnSettingsGroup } from './column_settings_group';
-import { ShowAnnouncementsButton } from './show_announcements_button';
+import { isRedesignEnabled } from '@/mastodon/utils/environment';
class ColumnSettings extends PureComponent {
static propTypes = {
@@ -47,10 +47,11 @@ class ColumnSettings extends PureComponent {
return (
-
+ {!isRedesignEnabled() &&
+
+ }
{alertsEnabled && browserSupport && browserPermission === 'denied' && (
diff --git a/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.module.scss b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.module.scss
new file mode 100644
index 00000000000..57d32a3089e
--- /dev/null
+++ b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.module.scss
@@ -0,0 +1,6 @@
+.lockup {
+ --lockup-padding-block: var(--space-3);
+
+ background: var(--color-bg-secondary);
+ border-radius: var(--radius-3);
+}
diff --git a/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx
index a1192867f5b..cec601ca042 100644
--- a/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx
+++ b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx
@@ -4,12 +4,19 @@ import { FormattedMessage, useIntl, defineMessages } from 'react-intl';
import { Link, useHistory } from 'react-router-dom';
+import { TrayIcon } from '@phosphor-icons/react';
+
+import { LockupLink, LockupWrapper } from '@/mastodon/components/lockup';
+import type { MastodonLocationDescriptor } from '@/mastodon/components/router';
+import { isRedesignEnabled } from '@/mastodon/utils/environment';
import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react';
import { fetchNotificationPolicy } from 'mastodon/actions/notification_policies';
import { Icon } from 'mastodon/components/icon';
import { selectSettingsNotificationsMinimizeFilteredBanner } from 'mastodon/selectors/settings';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
+import classes from './filtered_notifications_banner.module.scss';
+
const messages = defineMessages({
filteredNotifications: {
id: 'notification_requests.title',
@@ -80,28 +87,61 @@ export const FilteredNotificationsBanner: React.FC = () => {
}
return (
-
-
-
-
+ icon={
+ isRedesignEnabled() ? (
+
+ ) : (
+
+ )
+ }
+ title={
+
+ }
+ subtitle={
+
+ }
+ />
+ );
+};
+
+interface LinkBannerProps {
+ to: MastodonLocationDescriptor;
+ icon: React.ReactNode;
+ title: React.ReactNode;
+ subtitle: React.ReactNode;
+}
+
+export const LinkBanner: React.FC = ({
+ to,
+ icon,
+ title,
+ subtitle,
+}) => {
+ if (isRedesignEnabled()) {
+ return (
+
+
+ {title}
+
+
+ );
+ }
+ return (
+
+ {icon}
-
-
-
-
-
-
+ {title}
+ {subtitle}
);
diff --git a/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.tsx b/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.tsx
index 4bdee2567a4..906572a726b 100644
--- a/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.tsx
+++ b/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.tsx
@@ -2,13 +2,16 @@ import { useCallback } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
-import { messages as columnHeaderMessages } from '@/mastodon/components/column/header';
+import { GearIcon } from '@phosphor-icons/react';
+
+import { Button } from '@/mastodon/components/button/redesign';
import { useAppDispatch } from '@/mastodon/store';
+import { isRedesignEnabled } from '@/mastodon/utils/environment';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import UnfoldMoreIcon from '@/material-icons/400-24px/unfold_more.svg?react';
import { requestBrowserPermission } from 'mastodon/actions/notifications';
import { changeSetting } from 'mastodon/actions/settings';
-import { Button } from 'mastodon/components/button';
+import { Button as LegacyButton } from 'mastodon/components/button';
import { Icon } from 'mastodon/components/icon';
import { IconButton } from 'mastodon/components/icon_button';
@@ -53,19 +56,31 @@ const NotificationsPermissionBanner: React.FC = () => {
icon: (
),
}}
/>
-
+ {isRedesignEnabled() ? (
+
+ ) : (
+
+
+
+ )}
);
};
diff --git a/app/javascript/mastodon/features/notifications/components/show_announcements_button.tsx b/app/javascript/mastodon/features/notifications/components/show_announcements_button.tsx
deleted file mode 100644
index 4bf7661f0ff..00000000000
--- a/app/javascript/mastodon/features/notifications/components/show_announcements_button.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { useCallback } from 'react';
-
-import { FormattedMessage } from 'react-intl';
-
-import { NewspaperIcon } from '@phosphor-icons/react';
-
-import { showAnnouncements } from '@/mastodon/actions/announcements';
-import { closeModal } from '@/mastodon/actions/modal';
-import { Button } from '@/mastodon/components/button/redesign';
-import { useAppDispatch } from '@/mastodon/store';
-import { isRedesignEnabled } from '@/mastodon/utils/environment';
-
-import { useHasAnnouncements } from '../../announcements/hooks';
-
-export const ShowAnnouncementsButton: React.FC = () => {
- const dispatch = useAppDispatch();
- const { hasAnnouncements, shouldShowAnnouncements } = useHasAnnouncements({
- fetch: false,
- });
-
- const handleClick = useCallback(() => {
- dispatch(showAnnouncements());
- dispatch(
- closeModal({ modalType: 'NOTIFICATION_SETTINGS', ignoreFocus: false }),
- );
- }, [dispatch]);
-
- if (!isRedesignEnabled() || !hasAnnouncements || shouldShowAnnouncements) {
- return null;
- }
-
- return (
-
- );
-};
diff --git a/app/javascript/mastodon/features/notifications_v2/components/follow_requests_banner.tsx b/app/javascript/mastodon/features/notifications_v2/components/follow_requests_banner.tsx
index c20fa7587b2..a76f12772ad 100644
--- a/app/javascript/mastodon/features/notifications_v2/components/follow_requests_banner.tsx
+++ b/app/javascript/mastodon/features/notifications_v2/components/follow_requests_banner.tsx
@@ -1,12 +1,9 @@
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';
+import { LinkBanner } from '../../notifications/components/filtered_notifications_banner';
/**
* This banner is only shown to users whose notification policy filters
@@ -21,26 +18,22 @@ export const FollowRequestsBanner: React.FC = () => {
}
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ }
+ title={
+
+ }
+ subtitle={
+
+ }
+ />
);
};
diff --git a/app/javascript/mastodon/features/notifications_v2/index.tsx b/app/javascript/mastodon/features/notifications_v2/index.tsx
index 6ec3ccb45c5..9c5fc43a7ff 100644
--- a/app/javascript/mastodon/features/notifications_v2/index.tsx
+++ b/app/javascript/mastodon/features/notifications_v2/index.tsx
@@ -2,11 +2,17 @@ import { useCallback, useEffect, useMemo } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
-import { GearIcon } from '@phosphor-icons/react';
+import {
+ ChecksIcon,
+ GearIcon,
+ NewspaperIcon,
+ TrashIcon,
+} from '@phosphor-icons/react';
import { Helmet } from '@unhead/react/helmet';
import { isEqual } from 'lodash';
import { useDebouncedCallback } from 'use-debounce';
+import { toggleShowAnnouncements } from '@/mastodon/actions/announcements';
import {
addColumn,
removeColumn,
@@ -23,6 +29,7 @@ import {
} from '@/mastodon/components/column_header';
import { MultiColumnMenuItems } from '@/mastodon/components/column_header/multicolumn_settings';
import { LoadGap } from '@/mastodon/components/load_gap';
+import { MenuItem, MenuItemDivider } from '@/mastodon/components/menu';
import ScrollableList from '@/mastodon/components/scrollable_list';
import { isRedesignEnabled } from '@/mastodon/utils/environment';
import DoneAllIcon from '@/material-icons/400-24px/done_all.svg?react';
@@ -64,6 +71,7 @@ import ColumnSettingsContainer from '../notifications/containers/column_settings
import { FollowRequestsBanner } from './components/follow_requests_banner';
import { NotificationGroup } from './components/notification_group';
import { FilterBar } from './filter_bar';
+import classes from './styles.module.scss';
const messages = defineMessages({
title: { id: 'column.notifications', defaultMessage: 'Notifications' },
@@ -71,6 +79,10 @@ const messages = defineMessages({
id: 'notifications.mark_as_read',
defaultMessage: 'Mark every notification as read',
},
+ markAsReadRedesign: {
+ id: 'notifications.mark_all_as_read',
+ defaultMessage: 'Mark all as read',
+ },
});
export const Notifications: React.FC<{
@@ -172,11 +184,6 @@ export const Notifications: React.FC<{
[dispatch, columnId],
);
- const handleMarkAsRead = useCallback(() => {
- dispatch(markNotificationsAsRead());
- void dispatch(submitMarkers({ immediate: true }));
- }, [dispatch]);
-
const openSettingsModal = useCallback(() => {
dispatch(
openModal({
@@ -186,6 +193,21 @@ export const Notifications: React.FC<{
);
}, [dispatch]);
+ const handleMarkAsRead = useCallback(() => {
+ dispatch(markNotificationsAsRead());
+ void dispatch(submitMarkers({ immediate: true }));
+ }, [dispatch]);
+
+ const handleToggleAnnouncements = useCallback(() => {
+ dispatch(toggleShowAnnouncements());
+ }, [dispatch]);
+
+ const handleClearNotifications = useCallback(() => {
+ dispatch(
+ openModal({ modalType: 'CONFIRM_CLEAR_NOTIFICATIONS', modalProps: {} }),
+ );
+ }, [dispatch]);
+
const pinned = !!columnId;
const emptyMessage = (
{needsNotificationPermission && }
{shouldShowAnnouncements && }
-
-
+
+ {isRedesignEnabled() && }
+
+
>
);
@@ -292,17 +316,54 @@ export const Notifications: React.FC<{
defaultMessage='Notification Settings'
/>
- {multiColumn && (
-
+
+ {hasAnnouncements && (
+
+ )}
+
+
+ {multiColumn && (
-
- )}
+ )}
+
>
}
extraStickyContent={filterBar}
diff --git a/app/javascript/mastodon/features/notifications_v2/styles.module.scss b/app/javascript/mastodon/features/notifications_v2/styles.module.scss
new file mode 100644
index 00000000000..716add389bf
--- /dev/null
+++ b/app/javascript/mastodon/features/notifications_v2/styles.module.scss
@@ -0,0 +1,11 @@
+.topLinks {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-4);
+ margin: var(--space-4) var(--space-4) var(--space-2);
+
+ > * {
+ min-width: 250px;
+ flex: 1 1 0;
+ }
+}
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index af5835a4e8b..2d2249a9b25 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -1183,6 +1183,8 @@
"notifications.filter.statuses": "Updates from people you follow",
"notifications.grant_permission": "Grant permission.",
"notifications.group": "{count} notifications",
+ "notifications.hide_server_announcements": "Hide server announcements",
+ "notifications.mark_all_as_read": "Mark all as read",
"notifications.mark_as_read": "Mark every notification as read",
"notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request",
"notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before",