feat: 뉴스 미리보기 — AI 요약 상단 + 본문/메모 분리
- AI 요약: 파란 박스로 상단에 별도 표시 - 본문 입력: extracted_text에 추가 (기사 전문 붙여넣기) - 메모: user_note에 저장 (개인 메모) - 기사 선택 시 편집 상태 초기화 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,8 @@
|
|||||||
let currentPage = $state(1);
|
let currentPage = $state(1);
|
||||||
let noteEditing = $state(false);
|
let noteEditing = $state(false);
|
||||||
let noteText = $state('');
|
let noteText = $state('');
|
||||||
|
let contentEditing = $state(false);
|
||||||
|
let contentText = $state('');
|
||||||
let expandedSources = $state({});
|
let expandedSources = $state({});
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
@@ -71,6 +73,8 @@
|
|||||||
|
|
||||||
function selectArticle(article) {
|
function selectArticle(article) {
|
||||||
selectedArticle = article;
|
selectedArticle = article;
|
||||||
|
noteEditing = false;
|
||||||
|
contentEditing = false;
|
||||||
if (!article.is_read) markRead(article);
|
if (!article.is_read) markRead(article);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +99,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function saveContent() {
|
||||||
|
try {
|
||||||
|
// 본문은 extracted_text에 추가 (기존 요약 유지 + 본문 합산)
|
||||||
|
const newText = selectedArticle.extracted_text + '\n\n---\n\n' + contentText;
|
||||||
|
await api(`/documents/${selectedArticle.id}/content`, {
|
||||||
|
method: 'PUT',
|
||||||
|
body: JSON.stringify({ content: newText }),
|
||||||
|
});
|
||||||
|
selectedArticle.extracted_text = newText;
|
||||||
|
contentEditing = false;
|
||||||
|
addToast('success', '본문 저장됨');
|
||||||
|
} catch (e) {
|
||||||
|
addToast('error', '본문 저장 실패');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function saveNote() {
|
async function saveNote() {
|
||||||
try {
|
try {
|
||||||
await api(`/documents/${selectedArticle.id}`, {
|
await api(`/documents/${selectedArticle.id}`, {
|
||||||
@@ -269,35 +289,68 @@
|
|||||||
<!-- 본문 -->
|
<!-- 본문 -->
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<h2 class="text-lg font-bold mb-3">{selectedArticle.title}</h2>
|
<h2 class="text-lg font-bold mb-3">{selectedArticle.title}</h2>
|
||||||
|
|
||||||
|
<!-- AI 요약 -->
|
||||||
|
{#if selectedArticle.ai_summary}
|
||||||
|
<div class="mb-4 p-3 bg-[var(--accent)]/5 border border-[var(--accent)]/20 rounded-lg">
|
||||||
|
<h4 class="text-[10px] font-semibold text-[var(--accent)] uppercase mb-1">AI 요약</h4>
|
||||||
|
<div class="text-sm markdown-body">
|
||||||
|
{@html renderMd(selectedArticle.ai_summary)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<!-- RSS 원문 -->
|
||||||
<div class="markdown-body mb-4">
|
<div class="markdown-body mb-4">
|
||||||
{@html renderMd(selectedArticle.extracted_text || '')}
|
{@html renderMd(selectedArticle.extracted_text || '')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 본문 입력 -->
|
<!-- 본문 입력 -->
|
||||||
{#if noteEditing}
|
<div class="border-t border-[var(--border)] pt-4 mt-4">
|
||||||
<div class="mt-4 border-t border-[var(--border)] pt-4">
|
<h4 class="text-xs font-semibold text-[var(--text-dim)] mb-2">본문 입력</h4>
|
||||||
<h4 class="text-xs font-semibold text-[var(--text-dim)] mb-2">본문 / 메모 입력</h4>
|
{#if contentEditing}
|
||||||
|
<textarea
|
||||||
|
bind:value={contentText}
|
||||||
|
class="w-full h-32 px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg text-sm text-[var(--text)] resize-y outline-none focus:border-[var(--accent)]"
|
||||||
|
placeholder="기사 전문을 붙여넣으세요..."
|
||||||
|
></textarea>
|
||||||
|
<div class="flex gap-2 mt-2">
|
||||||
|
<button onclick={saveContent} class="px-3 py-1 text-xs bg-[var(--accent)] text-white rounded">저장</button>
|
||||||
|
<button onclick={() => contentEditing = false} class="px-3 py-1 text-xs text-[var(--text-dim)]">취소</button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
onclick={() => { contentText = ''; contentEditing = true; }}
|
||||||
|
class="text-xs text-[var(--text-dim)] hover:text-[var(--accent)]"
|
||||||
|
>+ 본문 입력</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 메모 -->
|
||||||
|
<div class="border-t border-[var(--border)] pt-4 mt-4">
|
||||||
|
<h4 class="text-xs font-semibold text-[var(--text-dim)] mb-2">메모</h4>
|
||||||
|
{#if noteEditing}
|
||||||
<textarea
|
<textarea
|
||||||
bind:value={noteText}
|
bind:value={noteText}
|
||||||
class="w-full h-32 px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg text-sm text-[var(--text)] resize-y outline-none focus:border-[var(--accent)]"
|
class="w-full h-20 px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg text-sm text-[var(--text)] resize-y outline-none focus:border-[var(--accent)]"
|
||||||
placeholder="기사 본문이나 메모를 입력하세요..."
|
placeholder="메모를 입력하세요..."
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="flex gap-2 mt-2">
|
<div class="flex gap-2 mt-2">
|
||||||
<button onclick={saveNote} class="px-3 py-1 text-xs bg-[var(--accent)] text-white rounded">저장</button>
|
<button onclick={saveNote} class="px-3 py-1 text-xs bg-[var(--accent)] text-white rounded">저장</button>
|
||||||
<button onclick={() => noteEditing = false} class="px-3 py-1 text-xs text-[var(--text-dim)]">취소</button>
|
<button onclick={() => noteEditing = false} class="px-3 py-1 text-xs text-[var(--text-dim)]">취소</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{:else}
|
||||||
{:else}
|
<button
|
||||||
<button
|
onclick={() => { noteText = selectedArticle.user_note || ''; noteEditing = true; }}
|
||||||
onclick={() => { noteText = selectedArticle.user_note || ''; noteEditing = true; }}
|
class="text-xs text-[var(--text-dim)] hover:text-[var(--accent)]"
|
||||||
class="mt-4 text-xs text-[var(--text-dim)] hover:text-[var(--accent)]"
|
>+ 메모 추가</button>
|
||||||
>+ 본문/메모 입력</button>
|
{#if selectedArticle.user_note}
|
||||||
{#if selectedArticle.user_note}
|
<div class="mt-2 p-3 bg-[var(--bg)] rounded-lg text-sm">
|
||||||
<div class="mt-2 p-3 bg-[var(--bg)] rounded-lg text-sm">
|
{selectedArticle.user_note}
|
||||||
{selectedArticle.user_note}
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
Reference in New Issue
Block a user