diff --git a/components/common/Alert.tsx b/components/common/Alert.tsx index 4f285925..e40d7439 100644 --- a/components/common/Alert.tsx +++ b/components/common/Alert.tsx @@ -1,3 +1,9 @@ +import { + ExclamationCircleIcon, + ExclamationTriangleIcon, + InformationCircleIcon, +} from '@heroicons/react/24/solid' + export const Alert = ({ type = 'info', title = '', @@ -19,16 +25,35 @@ export const Alert = ({ title: 'text-blue-800', }, warning: { - container: 'border-yellow-800 bg-yellow-200 text-yellow-800', + container: 'border-yellow-800 bg-yellow-200 text-yellow-600', title: 'text-yellow-800', }, } + const iconSize = !title || !body ? 'h-4 w-4' : 'h-6 w-6' + return (
- {title &&

{title}

} - {body &&

{body}

} + {showIcon && ( +
+ {type === 'error' && ( + + )} + {type === 'warning' && ( + + )} + {type === 'info' && ( + + )} +
+ )} +
+ {title &&

{title}

} + {body &&

{body}

} +
) } diff --git a/components/email/useEmailRecipientStatus.tsx b/components/email/useEmailRecipientStatus.tsx new file mode 100644 index 00000000..84e7fe1c --- /dev/null +++ b/components/email/useEmailRecipientStatus.tsx @@ -0,0 +1,33 @@ +import { DOMAINS_ALLOWING_EMAIL_COMMUNICATION } from '@/lib/constants' +import { resolveDidDocData } from '@/lib/identity' +import { useQuery } from '@tanstack/react-query' + +export const useEmailRecipientStatus = ( + did: string, +): { isLoading: boolean; error: any; cantReceive: boolean } => { + const { data, isLoading, error } = useQuery({ + queryKey: ['email-capability-check', did], + queryFn: async () => { + const response = await resolveDidDocData(did) + if (!response?.services) { + return false + } + + const pdsEndpoint = response.services['atproto_pds']?.endpoint + if (!pdsEndpoint) { + return false + } + + return DOMAINS_ALLOWING_EMAIL_COMMUNICATION.some((domain) => { + return !!domain && pdsEndpoint.endsWith(domain) + }) + }, + }) + + return { + isLoading, + error, + // we only know for sure that the recipient can't receive emails if the result of the query is false is false + cantReceive: data === false, + } +} diff --git a/components/repositories/AccountView.tsx b/components/repositories/AccountView.tsx index 0360dd1e..e9c0020a 100644 --- a/components/repositories/AccountView.tsx +++ b/components/repositories/AccountView.tsx @@ -18,7 +18,7 @@ import { } from '@heroicons/react/20/solid' import { AuthorFeed } from '../common/feeds/AuthorFeed' import { Json } from '../common/Json' -import { buildBlueSkyAppUrl, classNames, truncate } from '@/lib/util' +import { buildBlueSkyAppUrl, truncate } from '@/lib/util' import { ReportPanel } from '../reports/ReportPanel' import React from 'react' import { @@ -52,6 +52,8 @@ import { useWorkspaceRemoveItemsMutation, } from '@/workspace/hooks' import { Blocks } from './Blocks' +import { useEmailRecipientStatus } from 'components/email/useEmailRecipientStatus' +import { Alert } from '@/common/Alert' import { Follows } from 'components/graph/Follows' import { Followers } from 'components/graph/Followers' @@ -745,6 +747,7 @@ export const EventsView = ({ did }: { did: string }) => { } const EmailView = (props: ComponentProps) => { + const { cantReceive } = useEmailRecipientStatus(props.did) return (
@@ -758,6 +761,16 @@ const EmailView = (props: ComponentProps) => {
+ {cantReceive && ( +
+ +
+ )}
) diff --git a/lib/constants.ts b/lib/constants.ts index 7bd7a3b2..065ea141 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -40,3 +40,7 @@ export const YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process.env .NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS ? parseInt(process.env.NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS) : 30 + +export const DOMAINS_ALLOWING_EMAIL_COMMUNICATION = ( + process.env.NEXT_PUBLIC_DOMAINS_ALLOWING_EMAIL_COMMUNICATION || '' +).split(',')