fr1: books.ruzzy.dev — читалка с ИИ (PDF/EPUB → главы, рекапы, перевод/объяснение выделенного, вопросы с RAG; Claude Code по подписке без инструментов; вход через Telegram)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gilfanovr
2026-10-13 10:39:51 +03:00
co-authored by Claude Opus 5.5
parent 8fd84239be
commit 9aab5b3f40
19 changed files with 1455 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
{% extends "base.html" %}
{% block title %}{{ ch.title }} — {{ b.title }}{% endblock %}
{% block body %}
<nav class="row between small">
<a href="/book/{{ b.id }}">← {{ b.title }}</a>
<span>{% if ch.idx > 1 %}<a href="/book/{{ b.id }}/ch/{{ ch.idx - 1 }}">‹ пред.</a>{% endif %}
· {{ ch.idx }}/{{ n }} ·
{% if ch.idx < n %}<a href="/book/{{ b.id }}/ch/{{ ch.idx + 1 }}">след. ›</a>{% endif %}</span>
</nav>
<h1>{{ ch.title }}</h1>
<p class="small muted">с. {{ ch.p1 }}–{{ ch.p2 }} ·
<label><input type="checkbox" id="read" data-book="{{ b.id }}" data-ch="{{ ch.idx }}" {% if ch.read %}checked{% endif %}> прочитано</label>
· <a href="#recap">рекап</a> · <a href="/book/{{ b.id }}/file#page={{ ch.p1 }}" target="_blank">в оригинале</a></p>
<article id="text" class="reader" data-book="{{ b.id }}" data-ch="{{ ch.idx }}">{{ body|safe }}</article>
<section class="card" id="recap">
<div class="row between"><h2>Рекап</h2>
<button id="gen-recap" data-book="{{ b.id }}" data-ch="{{ ch.idx }}">{% if recap and recap.md %}Сделать заново{% else %}Сделать рекап{% endif %}</button></div>
<div id="recap-view" class="md">{{ recap.md if recap else '' }}</div>
<details><summary class="small muted">Править</summary>
<textarea id="recap-edit" rows="12">{{ recap.md if recap else '' }}</textarea>
<button id="save-recap" data-book="{{ b.id }}" data-ch="{{ ch.idx }}">Сохранить</button>
{% if recap and recap.ai_md and recap.ai_md != recap.md %}<p class="small muted">Есть более свежий вариант ИИ — <a href="#" id="use-ai">подставить</a></p>
<textarea id="ai-md" hidden>{{ recap.ai_md }}</textarea>{% endif %}
</details>
</section>
<section class="card">
<h2>Вопрос по главе</h2>
<form class="ask" data-book="{{ b.id }}" data-ch="{{ ch.idx }}">
<textarea name="q" rows="2" placeholder="Спроси о прочитанном"></textarea>
<div class="row"><button>Спросить</button>
<label class="small"><input type="checkbox" name="web"> проверить по интернету</label></div>
</form>
<div class="answer md"></div>
</section>
<div id="selbar" hidden>
<button data-act="translate">Перевести</button>
<button data-act="explain">Объяснить</button>
<button data-act="ask">Спросить…</button>
</div>
<div id="panel" hidden><div class="row between"><b id="panel-title"></b><button id="panel-close">✕</button></div>
<div id="panel-ask" hidden><textarea rows="2" placeholder="Вопрос о выделенном"></textarea>
<div class="row"><button id="panel-ask-go">Спросить</button><label class="small"><input type="checkbox" id="panel-web"> проверить по интернету</label></div></div>
<div id="panel-body" class="md"></div></div>
{% endblock %}