diff --git a/lib/routes/follow/profile.ts b/lib/routes/follow/profile.ts index 3667ad48efa17..d258c89af052e 100644 --- a/lib/routes/follow/profile.ts +++ b/lib/routes/follow/profile.ts @@ -2,11 +2,16 @@ import type { Data, Route } from '@/types'; import type { Context } from 'hono'; import ofetch from '@/utils/ofetch'; import type { FollowResponse, Profile, Subscription } from './types'; +import { parse } from 'tldts'; export const route: Route = { name: 'User subscriptions', + categories: ['social-media'], path: '/profile/:uid', - example: '/profile/41279032429549568', + example: '/follow/profile/41279032429549568', + parameters: { + uid: 'User ID or user handle', + }, radar: [ { source: ['app.follow.is/profile/:uid'], @@ -14,7 +19,7 @@ export const route: Route = { }, ], handler, - maintainers: ['KarasuShin'], + maintainers: ['KarasuShin', 'DIYgod'], features: { supportRadar: true, }, @@ -24,16 +29,40 @@ async function handler(ctx: Context): Promise { const uid = ctx.req.param('uid'); const host = 'https://api.follow.is'; - const [profile, subscriptions] = await Promise.all([ofetch>(`${host}/profiles?id=${uid}`), ofetch>(`${host}/subscriptions?userId=${uid}`)]); + const profile = await ofetch>(`${host}/profiles?id=${uid}`); + const subscriptions = await ofetch>(`${host}/subscriptions?userId=${profile.data.id}`); return { - title: `${profile.data.name} - User subscriptions`, + title: `${profile.data.name}'s subscriptions`, item: subscriptions.data.map((subscription) => ({ - title: subscription.feeds.title, + title: `Subscribed to ${subscription.feeds.title}`, description: subscription.feeds.description, link: `https://app.follow.is/feed/${subscription.feedId}`, + image: getUrlIcon(subscription.feeds.siteUrl).src, + category: [subscription.category], })), link: `https://app.follow.is/profile/${uid}`, image: profile.data.image, }; } + +const getUrlIcon = (url: string, fallback?: boolean | undefined) => { + let src: string; + let fallbackUrl = ''; + + try { + const { host } = new URL(url); + const pureDomain = parse(host).domainWithoutSuffix; + fallbackUrl = `https://avatar.vercel.sh/${pureDomain}.svg?text=${pureDomain?.slice(0, 2).toUpperCase()}`; + src = `https://unavatar.follow.is/${host}?fallback=${fallback || false}`; + } catch { + const pureDomain = parse(url).domainWithoutSuffix; + src = `https://avatar.vercel.sh/${pureDomain}.svg?text=${pureDomain?.slice(0, 2).toUpperCase()}`; + } + const ret = { + src, + fallbackUrl, + }; + + return ret; +};