Sifa professional network frontend (Next.js, React, TailwindCSS)
sifa.id/
1import type { PdsProviderInfo } from './types';
2
3export interface PdsProvider {
4 name: string;
5 profileUrl: string;
6 host?: string;
7}
8
9const BSKY_PROFILE_BASE = 'https://bsky.app/profile/';
10
11const PDS_PROVIDERS: { suffix: string; name: string }[] = [
12 { suffix: '.bsky.social', name: 'bluesky' },
13 { suffix: '.blacksky.app', name: 'blacksky' },
14 { suffix: '.eurosky.social', name: 'eurosky' },
15 { suffix: '.northsky.social', name: 'northsky' },
16];
17
18const KNOWN_PROVIDER_NAMES = new Set(PDS_PROVIDERS.map((p) => p.name));
19
20const ICON_ONLY_PROVIDERS = new Set(['selfhosted-social', 'selfhosted']);
21
22export function pdsProviderFromApi(
23 apiProvider: PdsProviderInfo | null | undefined,
24 handle: string,
25): PdsProvider | null {
26 if (!apiProvider) return null;
27 if (ICON_ONLY_PROVIDERS.has(apiProvider.name)) {
28 return { name: apiProvider.name, profileUrl: '', host: apiProvider.host };
29 }
30 if (!KNOWN_PROVIDER_NAMES.has(apiProvider.name)) return null;
31 return {
32 name: apiProvider.name,
33 profileUrl: `${BSKY_PROFILE_BASE}${handle}`,
34 host: apiProvider.host,
35 };
36}
37
38export function getHandleStem(handle: string): string {
39 const lower = handle.toLowerCase();
40 for (const provider of PDS_PROVIDERS) {
41 if (lower.endsWith(provider.suffix) && lower.length > provider.suffix.length) {
42 return handle.slice(0, -provider.suffix.length);
43 }
44 }
45 return handle;
46}
47
48export function getDisplayLabel(displayName: string | undefined, handle: string): string {
49 if (displayName) return displayName;
50 return getHandleStem(handle);
51}
52
53const PDS_DISPLAY_NAMES: Record<string, string> = {
54 bluesky: 'Bluesky',
55 blacksky: 'BlackSky',
56 eurosky: 'EuroSky',
57 northsky: 'NorthSky',
58 'selfhosted-social': 'Self-hosted',
59 selfhosted: 'Self-hosted',
60};
61
62export function getPdsDisplayName(providerName: string): string {
63 return PDS_DISPLAY_NAMES[providerName] ?? providerName;
64}
65
66export function detectPdsProvider(handle: string): PdsProvider | null {
67 const lower = handle.toLowerCase();
68 for (const provider of PDS_PROVIDERS) {
69 if (lower.endsWith(provider.suffix)) {
70 return {
71 name: provider.name,
72 profileUrl: `${BSKY_PROFILE_BASE}${handle}`,
73 };
74 }
75 }
76 return null;
77}