diff --git a/src/features/admin/hooks/useAdminNostrRelays.ts b/src/features/admin/hooks/useAdminNostrRelays.ts new file mode 100644 index 000000000..b55255135 --- /dev/null +++ b/src/features/admin/hooks/useAdminNostrRelays.ts @@ -0,0 +1,21 @@ +import { useQuery } from '@tanstack/react-query'; +import { z } from 'zod'; + +import { useApi } from 'soapbox/hooks'; + +const relayEntitySchema = z.object({ + url: z.string().url(), + marker: z.enum(['read', 'write']).optional(), +}); + +export function useAdminNostrRelays() { + const api = useApi(); + + return useQuery({ + queryKey: ['NostrRelay'], + queryFn: async () => { + const { data } = await api.get('/api/v1/admin/ditto/relays'); + return relayEntitySchema.array().parse(data); + }, + }); +} \ No newline at end of file diff --git a/src/features/admin/nostr-relays.tsx b/src/features/admin/nostr-relays.tsx new file mode 100644 index 000000000..40c7d719e --- /dev/null +++ b/src/features/admin/nostr-relays.tsx @@ -0,0 +1,55 @@ +import { useMutation } from '@tanstack/react-query'; +import React, { useEffect, useState } from 'react'; +import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; + +import { Button, Column, Form, FormActions, Stack } from 'soapbox/components/ui'; +import RelayEditor, { RelayData } from 'soapbox/features/nostr-relays/components/relay-editor'; +import { useApi } from 'soapbox/hooks'; + +import { useAdminNostrRelays } from './hooks/useAdminNostrRelays'; + +const messages = defineMessages({ + title: { id: 'column.admin.nostr_relays', defaultMessage: 'Relays' }, +}); + +const AdminNostrRelays: React.FC = () => { + const api = useApi(); + const intl = useIntl(); + const result = useAdminNostrRelays(); + + const [relays, setRelays] = useState(result.data ?? []); + + const mutation = useMutation({ + mutationFn: async () => api.put('/api/v1/admin/ditto/relays', relays), + }); + + const handleSubmit = () => { + mutation.mutate(); + }; + + useEffect(() => { + setRelays(result.data ?? []); + }, [result.data]); + + return ( + +
+ + + + + + + + + +
+
+ ); +}; + +export default AdminNostrRelays; \ No newline at end of file diff --git a/src/features/admin/tabs/dashboard.tsx b/src/features/admin/tabs/dashboard.tsx index bec02694d..f9a8e2ea2 100644 --- a/src/features/admin/tabs/dashboard.tsx +++ b/src/features/admin/tabs/dashboard.tsx @@ -113,6 +113,13 @@ const Dashboard: React.FC = () => { label={} /> )} + + {features.nostr && ( + } + /> + )} {account.admin && ( diff --git a/src/features/ui/index.tsx b/src/features/ui/index.tsx index 04b6e164f..95d9a9dab 100644 --- a/src/features/ui/index.tsx +++ b/src/features/ui/index.tsx @@ -142,6 +142,7 @@ import { Bech32Redirect, Relays, Rules, + AdminNostrRelays, } from './util/async-components'; import GlobalHotkeys from './util/global-hotkeys'; import { WrappedRoute } from './util/react-router-helpers'; @@ -334,6 +335,7 @@ const SwitchingColumnsArea: React.FC = ({ children }) => + {features.nostr && } {features.adminAnnouncements && } {features.domains && } {features.adminRules && } diff --git a/src/features/ui/util/async-components.ts b/src/features/ui/util/async-components.ts index 738cfc847..7d413bc5b 100644 --- a/src/features/ui/util/async-components.ts +++ b/src/features/ui/util/async-components.ts @@ -175,3 +175,4 @@ export const Bech32Redirect = lazy(() => import('soapbox/features/nostr/Bech32Re export const Relays = lazy(() => import('soapbox/features/admin/relays')); export const Rules = lazy(() => import('soapbox/features/admin/rules')); export const EditRuleModal = lazy(() => import('soapbox/features/ui/components/modals/edit-rule-modal')); +export const AdminNostrRelays = lazy(() => import('soapbox/features/admin/nostr-relays')); diff --git a/src/locales/en.json b/src/locales/en.json index 2467f62cf..64d7aa2f9 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -338,6 +338,7 @@ "column.admin.edit_domain": "Edit domain", "column.admin.edit_rule": "Edit rule", "column.admin.moderation_log": "Moderation Log", + "column.admin.nostr_relays": "Relays", "column.admin.relays": "Instance relays", "column.admin.reports": "Reports", "column.admin.reports.menu.moderation_log": "Moderation Log",