import { useState, useEffect } from 'react';
import ReactTimeAgo from 'react-time-ago';
import psl from 'psl';
import { default as lexicons, getLink, getContext } from 'lexicons';
import { resolveDid } from '../atproto/resolve';
import { Fetch } from './Fetch';
import './Notification.css';
export function fallbackRender({ error, resetErrorBoundary }) {
console.error('rendering fallback for error', error);
return (
sorry, something went wrong trying to show this notification
);
}
export function Notification({ app, group, source, source_record, source_did, subject, timestamp }) {
const [resolvedLink, setResolvedLink] = useState(null);
const [resolvedContext, setResolvedContext] = useState([]);
useEffect(() => {
(async () => {
const link = await getLink(source, source_record, subject);
if (link) setResolvedLink(link);
})();
(async() => {
const context = await getContext(source, source_record, subject);
setResolvedContext(context);
})();
}, [source, source_record, subject]);
// TODO: clean up / move this to lexicons package?
let title = source;
let icon;
let appName;
let appPrefix;
try {
appPrefix = app.split('.').toReversed().join('.');
} catch (e) {
console.error('getting top app failed', e);
}
const lex = lexicons[appPrefix];
icon = lex?.clients[0]?.icon;
let link = lex?.clients[0]?.notifications;
appName = lex?.name;
const sourceRemainder = source.slice(app.length + 1);
title = lex?.known_sources[sourceRemainder]?.name ?? source;
let directLink;
if (subject.startsWith('did:')) {
const s = source_record.slice('at://'.length).split('/');
const [sDid, sCollection, sRest] = [s[0], s[1], s.slice(2)]; // yeah did might be a handle oh well
directLink = lex
?.clients[0]
?.direct_links?.[`did:${sourceRemainder}`]
?.replace('{subject.did}', subject)
?.replace('{source_record.did}', sDid)
?.replace('{source_record.collection}', sCollection)
?.replace('{source_record.rkey}', sRest.join('/') || null);
} else if (subject.startsWith('at://')) {
let s = subject.slice('at://'.length).split('/');
const [did, collection, rest] = [s[0], s[1], s.slice(2)]; // yeah did might be a handle oh well
s = source_record.slice('at://'.length).split('/');
const [sDid, sCollection, sRest] = [s[0], s[1], s.slice(2)]; // yeah did might be a handle oh well
directLink = lex
?.clients[0]
?.direct_links?.[`at_uri:${sourceRemainder}`]
?.replace('{subject.did}', did)
?.replace('{subject.collection}', collection)
?.replace('{subject.rkey}', rest.join('/') || null)
?.replace('{source_record.did}', sDid)
?.replace('{source_record.collection}', sCollection)
?.replace('{source_record.rkey}', sRest.join('/') || null);
}
link = resolvedLink ?? directLink ?? link;
let contextClipped = resolvedContext.join(' ');
if (contextClipped.length > 240) {
contextClipped = contextClipped.slice(0, 239) + '…';
}
const contents = (
<>
{icon && (

)}
{title} from
{' '}
{source_did ? (
@{handle}}
/>
) : (
source_record
)}
{contextClipped.length > 0 && (
{contextClipped}
)}
{timestamp && (
)}
>
);
return link
?
{contents}
: {contents}
;
}