feat(projects): 등록 폼·카드 미리보기·README 가져오기 개선
- 등록 모달: 저장소 URL 필드를 제목 아래(설명 위)로 이동 — README 가져오기 흐름 자연화 - URL 미입력 상태로 README 가져오기 시 입력란에 빨간 인라인 안내 표시(토스트 대신) - 피드 카드: 설명 미리보기 2줄 클램프 + flex:1 로 태그·푸터를 카드 하단에 정렬 - fetchReadme: CRLF→LF·줄끝공백·연속빈줄 정리로 불필요한 개행 유입 방지 - mdPlain: 개행을 살려(빈 줄만 제거) 카드 미리보기가 README 줄 구조로 보이게 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
16
src/gitea.js
16
src/gitea.js
@@ -49,6 +49,20 @@ export async function fetchMainLang(repoUrl) {
|
||||
}
|
||||
}
|
||||
|
||||
// raw README 의 개행을 정리한다. Gitea 화면(렌더링)에는 없지만 raw 원문에 남아 있는
|
||||
// 군더더기 개행이 설명란에 "없던 엔터"처럼 들어오는 문제를 막는다.
|
||||
// - CRLF/CR → LF 로 통일(Windows 개행의 \r 제거)
|
||||
// - 줄 끝 공백 제거
|
||||
// - 3줄 이상 연속 빈 줄 → 빈 줄 1개(2개 개행)로 축소 (마크다운상 동일)
|
||||
// - 문서 앞뒤 공백/개행 제거
|
||||
function normalizeReadme(text) {
|
||||
return String(text)
|
||||
.replace(/\r\n?/g, "\n")
|
||||
.replace(/[ \t]+$/gm, "")
|
||||
.replace(/\n{3,}/g, "\n\n")
|
||||
.trim();
|
||||
}
|
||||
|
||||
// 레포의 README 원문(마크다운)을 반환. 실패/없음이면 "".
|
||||
// Gitea raw 엔드포인트로 기본 브랜치의 README 파일을 후보 순서대로 시도한다.
|
||||
export async function fetchReadme(repoUrl) {
|
||||
@@ -65,7 +79,7 @@ export async function fetchReadme(repoUrl) {
|
||||
for (const name of candidates) {
|
||||
const res = await fetch(`${base}/${name}`, { headers, signal: ctrl.signal });
|
||||
if (!res.ok) continue;
|
||||
const text = await res.text();
|
||||
const text = normalizeReadme(await res.text());
|
||||
// 너무 큰 README 는 앞부분만(설명란이 감당할 범위). 20KB 컷.
|
||||
return text.length > 20000 ? text.slice(0, 20000) : text;
|
||||
}
|
||||
|
||||
@@ -59,19 +59,23 @@ export function renderMarkdown(src) {
|
||||
return md.render(String(src || ""));
|
||||
}
|
||||
|
||||
// 카드 미리보기용 — 마크다운 기호를 걷어낸 순수 텍스트 한 덩어리.
|
||||
// (제목 #, 목록 -, 강조 *_`, 링크 [텍스트](url) → 텍스트, 코드펜스 ``` 제거)
|
||||
// 카드 미리보기용 — 마크다운 기호를 걷어낸 순수 텍스트. 줄바꿈은 살린다.
|
||||
// (제목 #, 목록 -, 강조 *_`, 링크 [텍스트](url) → 텍스트, 코드펜스/이미지/배지 제거)
|
||||
// 개행을 공백으로 뭉개지 않고 유지해, 2줄 클램프 미리보기가 README 앞부분의
|
||||
// 줄 구조 그대로 보이도록 한다(제목 줄 + 첫 설명 줄 등). 빈 줄은 없애 줄 낭비를 막는다.
|
||||
export function mdPlain(src) {
|
||||
return String(src || "")
|
||||
.replace(/```[\s\S]*?```/g, " ") // 코드펜스 블록 제거
|
||||
.replace(/`([^`]*)`/g, "$1") // 인라인 코드
|
||||
.replace(/!\[[^\]]*\]\([^)]*\)/g, " ") // 이미지
|
||||
.replace(/\[([^\]]*)\]\([^)]*\)/g, "$1") // 링크 → 텍스트
|
||||
.replace(/\[([^\]]*)\]\([^)]*\)/g, "$1") // 링크(배지 포함) → 텍스트
|
||||
.replace(/^\s{0,3}#{1,6}\s+/gm, "") // 제목 마커
|
||||
.replace(/^\s{0,3}>\s?/gm, "") // 인용 마커
|
||||
.replace(/^\s*[-*+]\s+/gm, "") // 목록 마커
|
||||
.replace(/[*_~]{1,3}/g, "") // 강조 기호
|
||||
.replace(/\s+/g, " ")
|
||||
.replace(/[ \t]+/g, " ") // 줄 안의 연속 공백만 축소(개행은 유지)
|
||||
.replace(/ *\n */g, "\n") // 줄 앞뒤 공백 제거
|
||||
.replace(/\n{2,}/g, "\n") // 빈 줄 제거 → 내용 줄만 남김
|
||||
.trim();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user