/* ============================================================================= * M02_MasterTemplete_Library_SameAsk.ts * 서고 같은 내용 물음(733-3 · 서버 꼴 = 733-2) — 사람 길(단가산출로 저장 · 공유 승인 · B09 내 자료집 …)이 * 같은 층 같은 내용이면 서버 409 `detail = {같은것: [{키, 이름, 층, 주인}], 까닭}` → * 물음 「같은 것 있음 — 그것을 씀 / 그래도 새로」 → 같은 부름을 몸 덧칸 `{씀: 키}` · `{새로: true}` 로 다시 · * 취소 = null. 물음 꼴 = 부품 `askChoice`. * ========================================================================== */ import { currentLanguageIndex } from "@ui/ui_template_locale"; import { askChoice } from "@ui/ui_template_modal"; import { StaleError } from "./M02_MasterTemplete_Api_Fetch"; const TEXT = { Title: ["같은 내용 있음", "Same content exists"], Message: [ "이 층에 내용이 같은 문서가 이미 있음 — {list}", "A document with the same content already exists on this layer — {list}", ], More: [" 외 {n}", " and {n} more"], Use: ["그것을 씀", "Use it"], New: ["그래도 새로", "Create anyway"], } as const; const tx = (key: keyof typeof TEXT): string => TEXT[key][currentLanguageIndex as 0 | 1] ?? TEXT[key][0]; export interface SameHit { 키: string; 이름: string; 층: string; 주인: string | null; } /** 다시 보낼 몸 덧칸 — 그것을 씀 = 그 키 · 그래도 새로 = 새 문서 */ export interface SameExtra { 씀?: string; 새로?: boolean; } /** 서버 409 몸에서 같은 내용 문서 목록 — 없으면 null(다른 409 = 판 · 같은 이름 …) */ export const sameHits = (detail: unknown): SameHit[] | null => { const list = (detail as { 같은것?: unknown } | null)?.같은것; return Array.isArray(list) && list.length ? (list as SameHit[]) : null; }; /** 물음 — 그것을 씀(첫 문서 = 먼저 만든 것) · 그래도 새로 · 취소 = null */ export async function askSame(hits: SameHit[]): Promise { const shown = hits.slice(0, 3).map((h) => `「${h.키} ${h.이름}」`); const more = hits.length > 3 ? tx("More").replace("{n}", String(hits.length - 3)) : ""; const got = await askChoice({ title: tx("Title"), message: tx("Message").replace("{list}", shown.join(" · ") + more), choices: [ { label: tx("New"), value: "new" }, { label: tx("Use"), value: "use" }, ], }); return got === "use" ? { 씀: hits[0].키 } : got === "new" ? { 새로: true } : null; } /** `job(덧칸)` — 409 같은것이면 물은 뒤 덧칸을 넣어 한 번 더 · 취소 = null · 그 밖 실패 = 그대로 던짐 */ export async function withSameAsk(job: (extra: SameExtra) => Promise): Promise { try { return await job({}); } catch (error) { const hits = error instanceof StaleError ? sameHits(error.detail) : null; if (!hits) throw error; const extra = await askSame(hits); return extra ? job(extra) : null; } }