diff --git a/apps/web/src/pages/plugins/[slug].astro b/apps/web/src/pages/plugins/[slug].astro index dadb2787b..79c88348b 100644 --- a/apps/web/src/pages/plugins/[slug].astro +++ b/apps/web/src/pages/plugins/[slug].astro @@ -1,17 +1,19 @@ --- +import PluginIcon from '@/components/PluginIcon.astro' import type { Plugin } from '@/config/plugins' import { actions } from '@/config/plugins' import Layout from '@/layouts/Layout.astro' import { createSoftwareApplicationLdJson } from '@/lib/ldJson' import * as m from '@/paraglide/messages' -import { getSlug } from '@/services/github' +import { getPluginsWithStars, getSlug } from '@/services/github' import { defaultLocale } from '@/services/locale' +import { getPluginDocsSlugs, resolvePluginDocsSlug } from '@/services/pluginDocs' +import { Icon as AstroIcon } from 'astro-icon/components' import type { GetStaticPaths } from 'astro' import type { CollectionEntry } from 'astro:content' import { getCollection } from 'astro:content' import { getRelativeLocaleUrl } from 'astro:i18n' import { marked } from 'marked' -import PluginIcon from '@/components/PluginIcon.astro' export const getStaticPaths: GetStaticPaths = async () => { const pluginPosts: { [k: string]: CollectionEntry<'plugin'>[] } = {} @@ -31,100 +33,58 @@ export const getStaticPaths: GetStaticPaths = async () => { }) } -// Get the plugin from the actions set -const plugin = actions.find((item) => getSlug(item.href) === Astro.params.slug) as Plugin +const locale = Astro.locals.locale ?? defaultLocale +const plugins = getPluginsWithStars(actions) +const plugin = plugins.find((item) => getSlug(item.href) === Astro.params.slug) if (!plugin || !plugin.title) return new Response(`plugin is not found for: ${Astro.url.pathname}`, { status: 404 }) let tutorialPlugin = '' const tutorialEntries = Astro.props.posts as CollectionEntry<'plugin'>[] -const thisTut = - tutorialEntries.find((i) => (i.data.locale || defaultLocale) === Astro.locals.locale) ?? tutorialEntries.find((i) => (i.data.locale || defaultLocale) === defaultLocale) +const thisTut = tutorialEntries.find((i) => (i.data.locale || defaultLocale) === locale) ?? tutorialEntries.find((i) => (i.data.locale || defaultLocale) === defaultLocale) + +const normalizeTutorialHeading = (html: string): string => { + return html.replace(/^(\s*)]*)>([\s\S]*?)<\/h1>/i, '$1$3') +} + if (thisTut?.body) tutorialPlugin = thisTut.body if (tutorialPlugin.length > 0) { const tmp = marked.parse(tutorialPlugin) - if (typeof tmp !== 'string') plugin['tutorial'] = await tmp - else plugin['tutorial'] = tmp + const tutorialHtml = typeof tmp !== 'string' ? await tmp : tmp + plugin['tutorial'] = normalizeTutorialHeading(tutorialHtml) } -plugin['githubStars'] = 0 -plugin['npmDownloads'] = 0 - const tmp = marked.parse(`# ${plugin.title}\n\n${plugin.description}`) if (typeof tmp !== 'string') plugin['readme'] = await tmp else plugin['readme'] = tmp -// const promises: any[] = [] - -// Fetch npm package details to get npm downloads -// const npmApiUrl = `https://api.npmjs.org/downloads/point/last-month/${plugin.name}` -// promises.push( -// fetch(npmApiUrl) -// .then((res) => (res.ok ? res.json() : null)) -// .then((res) => { -// if (res) plugin.npmDownloads = res.downloads -// }) -// .catch(() => {}), -// ) - -// Fetch npm package details to get npm modified -// const registryNpmApiUrl = `https://registry.npmjs.org/${plugin.name}` -// promises.push( -// fetch(registryNpmApiUrl) -// .then((res) => (res.ok ? res.json() : null)) -// .then((res) => { -// if (res) { -// plugin.datePublished = res.time.created -// plugin.dateModified = res.time.modified -// } -// }) -// .catch(() => {}), -// ) - -// Extract the GitHub repository owner and name from the URL -// const githubUrlParts = plugin.href.split('/') -// const githubOwner = githubUrlParts[3] -// const githubRepo = githubUrlParts[4] - -// Fetch GitHub repository details to get GitHub stars -// const githubApiUrl = `https://api.github.com/repos/${githubOwner}/${githubRepo}` -// promises.push( -// fetch(githubApiUrl) -// .then((res) => (res.ok ? res.json() : null)) -// .then((res) => { -// if (res) plugin.githubStars = res.stargazers_count -// }) -// .catch(() => {}), -// ) - -// Update the item with fetched data -// const readmeApiUrl = `https://api.github.com/repos/${githubOwner}/${githubRepo}/readme` -// promises.push( -// fetchWithToken(readmeApiUrl) -// .then((res) => (res.ok ? res.json() : null)) -// .then((res) => { -// if (res) { -// const tmp = marked.parse(Buffer.from(res.content, 'base64').toString('utf-8')) -// if (typeof tmp !== 'string') tmp.then((result) => (plugin.readme = result)) -// else plugin.readme = tmp -// } -// }) -// .catch(() => {}), -// ) - -// Await all the items to be fetched -// await Promise.all(promises) +const { localizedDocsSlugs, docsSlugs } = await getPluginDocsSlugs(locale) +const docsSlug = resolvePluginDocsSlug(plugin, docsSlugs) +const docsLocale = docsSlug && localizedDocsSlugs.has(docsSlug) ? locale : defaultLocale + +const formatCount = (count?: number): string => { + if (count === undefined) return 'n/a' + if (count >= 1000000) return `${(count / 1000000).toFixed(1)}M` + if (count >= 1000) return `${(count / 1000).toFixed(1)}k` + return count.toString() +} const { slug: id } = Astro.params +const { title, description, githubStars, npmDownloads, href, name, tutorial, icon, author } = plugin as Plugin + +const npmHref = name ? `https://www.npmjs.com/package/${name}` : undefined +const docsHref = docsSlug ? getRelativeLocaleUrl(docsLocale, `docs/plugins/${docsSlug}/`) : (npmHref ?? href) +const docsIsExternal = !docsSlug +const showRepoLink = href !== docsHref +const showNpmLink = !!npmHref && npmHref !== docsHref const content: { title?: string; description?: string; image?: string; author?: string; ldJSON?: Object } = {} if (plugin.title) content['title'] = `${plugin.title} Capacitor Plugin: Install, Setup & Examples` if (plugin.description) content['description'] = plugin.description -// Create improved ldJSON using helper function for SoftwareApplication -const pluginUrl = getRelativeLocaleUrl(Astro.locals.locale, `/plugins/${id}`) +const pluginUrl = getRelativeLocaleUrl(locale, `/plugins/${id}`) content['ldJSON'] = createSoftwareApplicationLdJson(Astro.locals.runtimeConfig.public, { name: plugin.title, @@ -132,110 +92,142 @@ content['ldJSON'] = createSoftwareApplicationLdJson(Astro.locals.runtimeConfig.p url: pluginUrl, applicationCategory: 'DeveloperApplication', operatingSystem: 'iOS, Android', - softwareVersion: '1.0.0', // Default version as plugin doesn't have version property downloadUrl: plugin.href, - aggregateRating: plugin.githubStars - ? { - ratingValue: Math.min(plugin.githubStars / 100, 5), // Normalize stars to 5-star scale - reviewCount: plugin.githubStars, - } - : undefined, }) - -const { title, description, githubStars, npmDownloads, href, name, tutorial, icon } = plugin --- -
- -
- - -
-
-