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:
@@ -2,14 +2,25 @@
|
||||
import { $, $$, toast } from "./util.js";
|
||||
import { applyReactions } from "./reactions.js";
|
||||
|
||||
// 저장소 URL 입력란의 빨간 안내(README 가져오기 전제)를 지운다.
|
||||
function clearRepoErr(m) {
|
||||
const err = $("#repoErr", m);
|
||||
const repoInput = $('input[name="repo_url"]', m);
|
||||
if (err) err.hidden = true;
|
||||
if (repoInput) repoInput.classList.remove("err");
|
||||
}
|
||||
|
||||
// 등록 모달의 "저장소 README 가져오기" — repo_url 의 README 를 받아 설명란을 채운다.
|
||||
async function importReadme() {
|
||||
const m = $("#shareModal"); if (!m) return;
|
||||
const btn = $("#readmeImport", m);
|
||||
const repoInput = $('input[name="repo_url"]', m);
|
||||
const err = $("#repoErr", m);
|
||||
const ta = $('textarea[name="description"]', m);
|
||||
const repo = ((repoInput && repoInput.value) || "").trim();
|
||||
if (!repo) { toast("먼저 저장소 URL 을 입력하세요"); if (repoInput) repoInput.focus(); return; }
|
||||
// URL 미입력 → 입력란 옆에 빨간 안내를 띄우고 포커스만 준다(토스트 대신 인라인).
|
||||
if (!repo) { if (err) err.hidden = false; if (repoInput) { repoInput.classList.add("err"); repoInput.focus(); } return; }
|
||||
clearRepoErr(m);
|
||||
if (ta && ta.value.trim() && !window.confirm("현재 설명 내용을 README 로 덮어쓸까요?")) return;
|
||||
const label = btn ? btn.innerHTML : "";
|
||||
if (btn) { btn.disabled = true; btn.textContent = "가져오는 중…"; }
|
||||
@@ -74,6 +85,7 @@ function openShare() {
|
||||
const h = $("#shareTitle", m); if (h) h.textContent = "새 프로젝트 등록";
|
||||
const sub = $("#shareSubmit", m); if (sub) sub.textContent = "등록";
|
||||
["title", "description", "tags", "repo_url", "app_url", "lang", "return_to"].forEach((n) => fieldSet(m, n, ""));
|
||||
clearRepoErr(m);
|
||||
setVis(m, true);
|
||||
m.hidden = false; document.body.style.overflow = "hidden";
|
||||
const t = $('input[name="title"]', m); if (t) t.focus();
|
||||
@@ -94,6 +106,7 @@ function openEdit(btn) {
|
||||
fieldSet(m, "lang", btn.getAttribute("data-lang"));
|
||||
fieldSet(m, "return_to", btn.getAttribute("data-return"));
|
||||
setVis(m, btn.getAttribute("data-public") === "1");
|
||||
clearRepoErr(m);
|
||||
m.hidden = false; document.body.style.overflow = "hidden";
|
||||
const t = $('input[name="title"]', m); if (t) { t.focus(); t.select(); }
|
||||
}
|
||||
@@ -138,5 +151,9 @@ export function initModals() {
|
||||
if (hint) hint.textContent = val === "public" ? "피드에 공개되어 동료가 볼 수 있어요" : "나만 볼 수 있어요 · 언제든 공유로 전환 가능";
|
||||
}
|
||||
});
|
||||
// 저장소 URL 을 입력하기 시작하면 빨간 안내를 즉시 지운다.
|
||||
document.addEventListener("input", (e) => {
|
||||
if (e.target && e.target.name === "repo_url") { const m = $("#shareModal"); if (m) clearRepoErr(m); }
|
||||
});
|
||||
document.addEventListener("keydown", (e) => { if (e.key === "Escape") { closeDetail(); closeShare(); } });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user