From 5f9988bf7d20d3964af7993dc6f7259dd20acf33 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Wed, 29 Apr 2026 14:45:13 +0200 Subject: [PATCH 1/3] improve plugin tutorial page actions --- apps/web/src/pages/plugins/[slug].astro | 312 ++++++++++++------------ 1 file changed, 150 insertions(+), 162 deletions(-) diff --git a/apps/web/src/pages/plugins/[slug].astro b/apps/web/src/pages/plugins/[slug].astro index dadb2787b..ed70ff293 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,15 +33,15 @@ 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) if (thisTut?.body) tutorialPlugin = thisTut.body if (tutorialPlugin.length > 0) { @@ -48,83 +50,34 @@ if (tutorialPlugin.length > 0) { else plugin['tutorial'] = tmp } -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 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 +85,145 @@ 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 + softwareVersion: '1.0.0', downloadUrl: plugin.href, aggregateRating: plugin.githubStars ? { - ratingValue: Math.min(plugin.githubStars / 100, 5), // Normalize stars to 5-star scale + ratingValue: Math.min(plugin.githubStars / 100, 5), reviewCount: plugin.githubStars, } : undefined, }) - -const { title, description, githubStars, npmDownloads, href, name, tutorial, icon } = plugin --- -
- -
- - -
-
-