Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 60 additions & 8 deletions app/pages/code/[...path].vue
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,22 @@ const canonicalUrl = computed(() => {
return url
})

// Toggle markdown view mode
const markdownViewModes = [
{
key: 'preview',
label: $t('code.markdown_view_mode.preview'),
icon: 'i-carbon-view',
},
{
key: 'code',
label: $t('code.markdown_view_mode.code'),
icon: 'i-carbon-code',
},
] as const

const markdownViewMode = ref<(typeof markdownViewModes)[number]['key']>('preview')

useHead({
link: [{ rel: 'canonical', href: canonicalUrl }],
})
Expand Down Expand Up @@ -359,15 +375,39 @@ useSeoMeta({
<!-- File viewer -->
<template v-if="isViewingFile && fileContent">
<div
class="sticky top-0 bg-bg border-b border-border px-4 py-2 flex items-center justify-between"
class="sticky z-10 top-0 bg-bg border-b border-border px-4 py-2 flex items-center justify-between"
>
<div class="flex items-center gap-3 text-sm">
<span class="text-fg-muted">{{
$t('code.lines', { count: fileContent.lines })
}}</span>
<span v-if="currentNode?.size" class="text-fg-subtle">{{
formatBytes(currentNode.size)
}}</span>
<div class="flex items-center gap-2">
<div
v-if="fileContent.markdownHtml"
class="flex items-center gap-1 p-0.5 bg-bg-subtle border border-border-subtle rounded-md overflow-x-auto"
role="tablist"
aria-label="Markdown view mode selector"
>
<button
v-for="mode in markdownViewModes"
:key="mode.key"
role="tab"
class="px-2 py-1.5 font-mono text-xs rounded transition-colors duration-150 border border-solid focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 inline-flex items-center gap-1.5"
:class="
markdownViewMode === mode.key
? 'bg-bg shadow text-fg border-border'
: 'text-fg-subtle hover:text-fg border-transparent'
"
@click="markdownViewMode = mode.key"
>
<span class="inline-block h-3 w-3" :class="mode.icon" aria-hidden="true" />
{{ mode.label }}
</button>
</div>
<div class="flex items-center gap-3 text-sm">
<span class="text-fg-muted">{{
$t('code.lines', { count: fileContent.lines })
}}</span>
<span v-if="currentNode?.size" class="text-fg-subtle">{{
formatBytes(currentNode.size)
}}</span>
</div>
</div>
<div class="flex items-center gap-2">
<button
Expand All @@ -389,7 +429,19 @@ useSeoMeta({
</a>
</div>
</div>
<div
v-if="fileContent.markdownHtml"
v-show="markdownViewMode === 'preview'"
class="flex justify-center p-4"
>
<div
class="readme-content prose prose-invert max-w-[70ch]"
v-html="fileContent.markdownHtml.html"
></div>
</div>

<CodeViewer
v-show="!fileContent.markdownHtml || markdownViewMode === 'code'"
:html="fileContent.html"
:lines="fileContent.lines"
:selected-lines="selectedLines"
Expand Down
4 changes: 4 additions & 0 deletions i18n/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@
"table": {
"name": "الاسم",
"size": "الحجم"
},
"markdown_view_mode": {
"preview": "معاينة",
"code": "الكود"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions i18n/locales/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@
"table": {
"name": "Name",
"size": "Größe"
},
"markdown_view_mode": {
"preview": "Vorschau",
"code": "Code"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,10 @@
"table": {
"name": "Name",
"size": "Size"
},
"markdown_view_mode": {
"preview": "preview",
"code": "code"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions i18n/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,10 @@
"table": {
"name": "Nombre",
"size": "Tamaño"
},
"markdown_view_mode": {
"preview": "vista previa",
"code": "código"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions i18n/locales/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,10 @@
"table": {
"name": "Nom",
"size": "Taille"
},
"markdown_view_mode": {
"preview": "aperçu",
"code": "code"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions i18n/locales/it-IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,10 @@
"table": {
"name": "Nome",
"size": "Dimensione"
},
"markdown_view_mode": {
"preview": "anteprima",
"code": "codice"
}
},
"filters": {
Expand Down
4 changes: 4 additions & 0 deletions i18n/locales/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,10 @@
"table": {
"name": "名前",
"size": "サイズ"
},
"markdown_view_mode": {
"preview": "プレビュー",
"code": "コード"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,10 @@
"table": {
"name": "名称",
"size": "大小"
},
"markdown_view_mode": {
"preview": "预览",
"code": "代码"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@
"table": {
"name": "الاسم",
"size": "الحجم"
},
"markdown_view_mode": {
"preview": "معاينة",
"code": "الكود"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@
"table": {
"name": "Name",
"size": "Größe"
},
"markdown_view_mode": {
"preview": "Vorschau",
"code": "Code"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,10 @@
"table": {
"name": "Name",
"size": "Size"
},
"markdown_view_mode": {
"preview": "preview",
"code": "code"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/es-419.json
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,10 @@
"table": {
"name": "Nombre",
"size": "Tamaño"
},
"markdown_view_mode": {
"preview": "vista previa",
"code": "código"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,10 @@
"table": {
"name": "Nombre",
"size": "Tamaño"
},
"markdown_view_mode": {
"preview": "vista previa",
"code": "código"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,10 @@
"table": {
"name": "Nom",
"size": "Taille"
},
"markdown_view_mode": {
"preview": "aperçu",
"code": "code"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/it-IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,10 @@
"table": {
"name": "Nome",
"size": "Dimensione"
},
"markdown_view_mode": {
"preview": "anteprima",
"code": "codice"
}
},
"filters": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,10 @@
"table": {
"name": "名前",
"size": "サイズ"
},
"markdown_view_mode": {
"preview": "プレビュー",
"code": "コード"
}
},
"badges": {
Expand Down
4 changes: 4 additions & 0 deletions lunaria/files/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,10 @@
"table": {
"name": "名称",
"size": "大小"
},
"markdown_view_mode": {
"preview": "预览",
"code": "代码"
}
},
"badges": {
Expand Down
14 changes: 14 additions & 0 deletions server/api/registry/file/[...pkg].get.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as v from 'valibot'
import { PackageFileQuerySchema } from '#shared/schemas/package'
import type { ReadmeResponse } from '#shared/types/readme'
import {
CACHE_MAX_AGE_ONE_YEAR,
ERROR_PACKAGE_VERSION_AND_FILE_FAILED,
Expand Down Expand Up @@ -166,6 +167,18 @@ export default defineCachedEventHandler(
resolveRelative,
})

let markdownHtml: ReadmeResponse | undefined
if (language === 'markdown') {
// Best-effort: markdown preview is optional; never block code view
try {
const packageData = await fetchNpmPackage(rawPackageName)
const repoInfo = parseRepositoryInfo(packageData.repository)
markdownHtml = await renderReadmeHtml(content, rawPackageName, repoInfo)
} catch {
markdownHtml = undefined
}
}

return {
package: packageName,
version,
Expand All @@ -174,6 +187,7 @@ export default defineCachedEventHandler(
content,
html,
lines: content.split('\n').length,
markdownHtml,
}
} catch (error: unknown) {
handleApiError(error, {
Expand Down
2 changes: 2 additions & 0 deletions shared/types/npm-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import type { PackumentVersion } from '@npm/types'
import type { ReadmeResponse } from './readme'

// Re-export official npm types for packument/manifest
export type {
Expand Down Expand Up @@ -325,4 +326,5 @@ export interface PackageFileContentResponse {
content: string
html: string
lines: number
markdownHtml?: ReadmeResponse
}