From f95fd3b562badcabcf1b8409d8b921244d2277f1 Mon Sep 17 00:00:00 2001 From: anonymousRecords Date: Sat, 29 Aug 2026 17:55:25 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=83=9D=EC=84=B1=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=A7=88=ED=81=AC=EB=8B=A4=EC=9A=B4=EC=9D=84=20git-style=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=EB=A1=9C=20=EA=B0=90=EC=8B=B8=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub은 링크 없는 마크다운 이미지를 렌더링할 때 camo 프록시 URL을 가리키는 로 자동 감싼다. 그 결과 사용자가 프로필에 붙인 배지를 클릭하면 camo.githubusercontent.com의 원본 PNG로 이동했다. 명시적 링크를 주면 GitHub이 이를 보존하므로, 생성 스니펫을 [![...](...)](https://git-style.vercel.app) 형태로 변경했다. 마크다운 조립 로직이 PreviewCard 본문에 인라인으로 있어 컴포넌트 외부에서 검증할 수 없었으므로, 순수 함수로 lib/utils/markdown.ts에 추출한 뒤 동작을 변경했다. 쿼리스트링 생성 규칙은 그대로다. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01La1oXcrwEZycnLJGdkFn3y --- components/ui/PreviewCard.tsx | 36 ++++++++++++---------------- lib/utils/markdown.ts | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 lib/utils/markdown.ts diff --git a/components/ui/PreviewCard.tsx b/components/ui/PreviewCard.tsx index 6278537..5d46c87 100644 --- a/components/ui/PreviewCard.tsx +++ b/components/ui/PreviewCard.tsx @@ -4,6 +4,7 @@ import Image from "next/image"; import { usePostHog } from "posthog-js/react"; import { useState } from "react"; import type { FlowerType, HairCurliness } from "@/lib/themes/types"; +import { buildAnimationPath, buildMarkdown } from "@/lib/utils/markdown"; interface PreviewCardProps { username: string; @@ -20,27 +21,20 @@ export default function PreviewCard({ hairColor, curliness, }: PreviewCardProps) { - const isHairTheme = hairColor !== undefined || curliness !== undefined; - const theme = isHairTheme ? "hair" : "flower"; - - let params = `theme=${theme}&quality=low`; - - if (theme === "flower") { - params += `&flower=${flowerType || "default"}`; - if (flowerColor) { - params += `&color=${encodeURIComponent(flowerColor)}`; - } - } else if (theme === "hair") { - if (hairColor) { - params += `&color=${encodeURIComponent(hairColor)}`; - } - if (curliness) { - params += `&curliness=${curliness}`; - } - } - - const animationUrl = `/api/${username}/animation?${params}`; - const markdown = `![GitStyle](https://git-style.vercel.app${animationUrl})`; + const animationUrl = buildAnimationPath({ + username, + flowerType, + flowerColor, + hairColor, + curliness, + }); + const markdown = buildMarkdown({ + username, + flowerType, + flowerColor, + hairColor, + curliness, + }); const [isLoading, setIsLoading] = useState(true); const [hasError, setHasError] = useState(false); diff --git a/lib/utils/markdown.ts b/lib/utils/markdown.ts new file mode 100644 index 0000000..4449d28 --- /dev/null +++ b/lib/utils/markdown.ts @@ -0,0 +1,44 @@ +import type { FlowerType, HairCurliness } from "@/lib/themes/types"; + +export const SITE_URL = "https://git-style.vercel.app"; + +export interface AnimationOptions { + username: string; + flowerType?: FlowerType; + flowerColor?: string; + hairColor?: string; + curliness?: HairCurliness; +} + +export function buildAnimationPath({ + username, + flowerType, + flowerColor, + hairColor, + curliness, +}: AnimationOptions): string { + const isHairTheme = hairColor !== undefined || curliness !== undefined; + const theme = isHairTheme ? "hair" : "flower"; + + let params = `theme=${theme}&quality=low`; + + if (theme === "flower") { + params += `&flower=${flowerType || "default"}`; + if (flowerColor) { + params += `&color=${encodeURIComponent(flowerColor)}`; + } + } else { + if (hairColor) { + params += `&color=${encodeURIComponent(hairColor)}`; + } + if (curliness) { + params += `&curliness=${curliness}`; + } + } + + return `/api/${username}/animation?${params}`; +} + +export function buildMarkdown(options: AnimationOptions): string { + return `[![GitStyle](${SITE_URL}${buildAnimationPath(options)})](${SITE_URL})`; +}