diff --git a/src/components/sidebar-navigation.tsx b/src/components/sidebar-navigation.tsx
index d0868f294..b771c1eb8 100644
--- a/src/components/sidebar-navigation.tsx
+++ b/src/components/sidebar-navigation.tsx
@@ -5,6 +5,7 @@ import { Stack } from 'soapbox/components/ui';
import { useStatContext } from 'soapbox/contexts/stat-context';
import ComposeButton from 'soapbox/features/ui/components/compose-button';
import { useAppSelector, useFeatures, useOwnAccount, useSettings, useInstance } from 'soapbox/hooks';
+import { useSettingsNotifications } from 'soapbox/hooks/useSettingsNotifications';
import DropdownMenu, { Menu } from './dropdown-menu';
import SidebarNavigationLink from './sidebar-navigation-link';
@@ -30,6 +31,7 @@ const SidebarNavigation = () => {
const notificationCount = useAppSelector((state) => state.notifications.unread);
const followRequestsCount = useAppSelector((state) => state.user_lists.follow_requests.items.count());
const dashboardCount = useAppSelector((state) => state.admin.openReports.count() + state.admin.awaitingApproval.count());
+ const settingsNotifications = useSettingsNotifications();
const restrictUnauth = instance.pleroma.metadata.restrict_unauthenticated;
@@ -160,7 +162,7 @@ const SidebarNavigation = () => {
icon={require('@tabler/icons/outline/settings.svg')}
activeIcon={require('@tabler/icons/filled/settings.svg')}
text={}
- count={features.nip05 && account.acct !== account.source?.nostr?.nip05 ? 1 : 0}
+ count={settingsNotifications.size}
/>
{account.staff && (
diff --git a/src/features/edit-identity/index.tsx b/src/features/edit-identity/index.tsx
index d4800202c..ab9436241 100644
--- a/src/features/edit-identity/index.tsx
+++ b/src/features/edit-identity/index.tsx
@@ -1,11 +1,12 @@
import { useMutation, useQuery } from '@tanstack/react-query';
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { patchMe } from 'soapbox/actions/me';
+import { changeSetting } from 'soapbox/actions/settings';
import List, { ListItem } from 'soapbox/components/list';
import { Button, CardHeader, CardTitle, Column, Emoji, Form, HStack, Icon, Input, Textarea, Tooltip } from 'soapbox/components/ui';
-import { useApi, useAppDispatch, useInstance, useOwnAccount } from 'soapbox/hooks';
+import { useApi, useAppDispatch, useInstance, useOwnAccount, useSettings } from 'soapbox/hooks';
import { queryClient } from 'soapbox/queries/client';
import { adminAccountSchema } from 'soapbox/schemas/admin-account';
import toast from 'soapbox/toast';
@@ -33,10 +34,20 @@ const EditIdentity: React.FC = () => {
const { data: approvedNames } = useNames();
const { data: pendingNames } = usePendingNames();
+ const { dismissedSettingsNotifications } = useSettings();
const [username, setUsername] = useState('');
const [reason, setReason] = useState('');
+ useEffect(() => {
+ const dismissed = new Set(dismissedSettingsNotifications);
+
+ if (!dismissed.has('needsNip05')) {
+ dismissed.add('needsNip05');
+ dispatch(changeSetting(['dismissedSettingsNotifications'], [...dismissed]));
+ }
+ }, []);
+
if (!account) return null;
const updateName = async (name: string): Promise => {
diff --git a/src/features/settings/index.tsx b/src/features/settings/index.tsx
index 30a9c2dc8..bdc0b655f 100644
--- a/src/features/settings/index.tsx
+++ b/src/features/settings/index.tsx
@@ -6,6 +6,7 @@ import CopyableInput from 'soapbox/components/copyable-input';
import List, { ListItem } from 'soapbox/components/list';
import { Card, CardBody, CardHeader, CardTitle, Column, Counter, FormGroup, Text } from 'soapbox/components/ui';
import { useAppDispatch, useAppSelector, useFeatures, useInstance, useOwnAccount } from 'soapbox/hooks';
+import { useSettingsNotifications } from 'soapbox/hooks/useSettingsNotifications';
import Preferences from '../preferences';
@@ -46,6 +47,7 @@ const Settings = () => {
const features = useFeatures();
const { account } = useOwnAccount();
const instance = useInstance();
+ const settingsNotifications = useSettingsNotifications();
const isMfaEnabled = mfa.getIn(['settings', 'totp']);
@@ -73,7 +75,7 @@ const Settings = () => {
{account?.source?.nostr?.nip05}
- {features.nip05 && }
+ {settingsNotifications.has('needsNip05') && }
)}
diff --git a/src/hooks/useSettingsNotifications.ts b/src/hooks/useSettingsNotifications.ts
new file mode 100644
index 000000000..f8ab9ab78
--- /dev/null
+++ b/src/hooks/useSettingsNotifications.ts
@@ -0,0 +1,25 @@
+import { useFeatures } from './useFeatures';
+import { useOwnAccount } from './useOwnAccount';
+import { useSettings } from './useSettings';
+
+type SettingsNotification = 'needsNip05';
+
+/** Get a list of notifications for settings. */
+export function useSettingsNotifications(): Set {
+ const notifications: Set = new Set();
+
+ const features = useFeatures();
+ const { account } = useOwnAccount();
+ const { dismissedSettingsNotifications } = useSettings();
+
+ if (
+ !dismissedSettingsNotifications.includes('needsNip05')
+ && account
+ && features.nip05
+ && account.acct !== account.source?.nostr?.nip05
+ ) {
+ notifications.add('needsNip05');
+ }
+
+ return notifications;
+}
\ No newline at end of file
diff --git a/src/schemas/soapbox/settings.ts b/src/schemas/soapbox/settings.ts
index e052720ba..e1b8fe53c 100644
--- a/src/schemas/soapbox/settings.ts
+++ b/src/schemas/soapbox/settings.ts
@@ -73,6 +73,8 @@ const settingsSchema = z.object({
show: z.boolean().catch(true),
}),
}),
+ /** Settings notifications that have been dismissed. See `useSettingsNotifications` hook. */
+ dismissedSettingsNotifications: z.array(z.string()).catch([]),
});
type Settings = z.infer;