feat(memoir+conversation): 章节/故事最小可读字数;会话 hasUserMessage 与 UI 优化

- 后端:300 字门槛统一物化、hydrate、列表/PDF/详情;过短章节对读者隐藏
- 对话:首包前打字动画、大字模式排版、朗读/TTS 交互与布局稳定
- 首页:复用无用户消息会话;空列表「继续对话」与文案 i18n
- 章节阅读:标题进正文、封面与去重标题;阅读 Markdown 字号上调
This commit is contained in:
Kevin
2026-03-26 16:28:33 +08:00
parent d990399112
commit 1374f6e8f5
15 changed files with 708 additions and 198 deletions

View File

@@ -8,6 +8,9 @@ PDF 导出可单独物化「## 标题 + 正文」版本。
from typing import Any
from app.features.memoir.markdown_sanitize import sanitize_story_for_chapter_compose
from app.features.memoir.reading_segment_materialize import (
story_meets_minimum_chapter_length,
)
def _gather_title_body_pairs(chapter: Any) -> list[tuple[str, str]]:
@@ -37,7 +40,7 @@ def compose_ordered_stories_to_markdown(ordered: list[tuple[str, str]]) -> str:
if not raw:
continue
cleaned = sanitize_story_for_chapter_compose(raw, title)
if cleaned:
if cleaned and story_meets_minimum_chapter_length(cleaned):
bodies.append(cleaned)
return "\n\n---\n\n".join(bodies)
@@ -53,6 +56,8 @@ def compose_ordered_stories_to_pdf_markdown(ordered: list[tuple[str, str]]) -> s
body = sanitize_story_for_chapter_compose(raw, title)
if not body:
continue
if not story_meets_minimum_chapter_length(body):
continue
parts.append(f"## {t}\n\n{body}")
return "\n\n---\n\n".join(parts)