95 lines
2.4 KiB
TypeScript
95 lines
2.4 KiB
TypeScript
import KVStore from '@/storage/kv-store';
|
|
|
|
type DomainCapabilities = {
|
|
lastChecked: number;
|
|
} & (
|
|
| {
|
|
failed: true;
|
|
}
|
|
| {
|
|
failed: false;
|
|
emojiReacts: boolean;
|
|
}
|
|
);
|
|
|
|
interface Capabilities {
|
|
_version: number;
|
|
domains: Record<string, DomainCapabilities>;
|
|
}
|
|
|
|
let capabilities: Capabilities = {
|
|
_version: 1,
|
|
domains: {},
|
|
};
|
|
|
|
const getCapabilitiesFromMemory = () =>
|
|
KVStore.getItem<Capabilities>('instanceCapabilities')
|
|
.then((capabilitiesFromMemory) => {
|
|
if (capabilitiesFromMemory) {
|
|
capabilities = capabilitiesFromMemory;
|
|
}
|
|
})
|
|
.catch(() => {});
|
|
|
|
const checkEmojiReactsSupport = (instance: Record<string, any>) =>
|
|
instance.configuration?.reactions?.max_reactions > 0 ||
|
|
instance.pleroma?.metadata?.features?.includes('pleroma_emoji_reactions');
|
|
|
|
const setDomainCapabilities = async (domain: string, domainCapabilities: DomainCapabilities) => {
|
|
await getCapabilitiesFromMemory();
|
|
capabilities.domains[domain] = domainCapabilities;
|
|
await KVStore.setItem('instanceCapabilities', capabilities);
|
|
};
|
|
|
|
const fetchCapabilities = async (domain: string): Promise<DomainCapabilities> => {
|
|
try {
|
|
const response = await fetch(`https://${domain}/api/v1/instance`, {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
}).then((res) => res.json());
|
|
|
|
const emojiReacts = checkEmojiReactsSupport(response);
|
|
|
|
const domainCapabilities: DomainCapabilities = {
|
|
lastChecked: Date.now(),
|
|
failed: false,
|
|
emojiReacts,
|
|
};
|
|
await setDomainCapabilities(domain, domainCapabilities);
|
|
return domainCapabilities;
|
|
} catch (e) {
|
|
const domainCapabilities: DomainCapabilities = {
|
|
lastChecked: Date.now(),
|
|
failed: true,
|
|
};
|
|
await setDomainCapabilities(domain, domainCapabilities);
|
|
return domainCapabilities;
|
|
}
|
|
};
|
|
|
|
const supportsEmojiReacts = async (accountUrl: string): Promise<'true' | 'false' | 'unknown'> => {
|
|
const domain = new URL(accountUrl).hostname;
|
|
let domainCapabilities = capabilities.domains[domain];
|
|
|
|
if (
|
|
!domainCapabilities ||
|
|
domainCapabilities.lastChecked <
|
|
Date.now() - 1000 * 60 * 60 * 24 * (domainCapabilities.failed ? 1 : 7)
|
|
) {
|
|
domainCapabilities = await fetchCapabilities(domain);
|
|
}
|
|
|
|
if (domainCapabilities.failed) {
|
|
return 'unknown';
|
|
}
|
|
if (domainCapabilities.emojiReacts) {
|
|
return 'true';
|
|
}
|
|
return 'false';
|
|
};
|
|
|
|
getCapabilitiesFromMemory();
|
|
|
|
export { supportsEmojiReacts };
|