diff --git a/app/components/Markdown/ShikiHighlight.vue b/app/components/Markdown/ShikiHighlight.vue index e863a2b..0e80170 100644 --- a/app/components/Markdown/ShikiHighlight.vue +++ b/app/components/Markdown/ShikiHighlight.vue @@ -5,16 +5,31 @@ const props = defineProps<{ code: string; language: string }>(); const start = Date.now(); +const MAX_LENGTH = 15000; + const renderId = `${useId()}-${hashSync(props.code + props.language)}`; const copied = ref(false); const collapsed = ref(false); +const showFull = ref(false); + +const isTruncated = computed(() => props.code.length > MAX_LENGTH); +const displayCode = computed(() => isTruncated.value && !showFull.value ? props.code.slice(0, MAX_LENGTH) : props.code); + +function formatSize(bytes: number): string { + if (bytes < 1024) return `${bytes}B`; + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}kB`; + if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`; + return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}GB`; +} + +const fullSizeFormatted = computed(() => formatSize(props.code.length)); const { $shiki } = useNuxtApp(); const { data: parsed, clear } = await useAsyncData(`shiki-${renderId}`, - () => parseCode(props.code, props.language.toLowerCase()), + () => parseCode(displayCode.value, props.language.toLowerCase()), { - watch: [() => props.code], + watch: [displayCode], dedupe: 'defer' } ); @@ -72,6 +87,14 @@ console.log("shiki codeblock rendered in", Date.now() - start); {{ parsed?.displayLang }}
+ +