anc
Ход работы не теряется при уходе с экрана; без «Записать» в шапке и предупреждения
- jobs.ts: расшифровка и ответ ИИ живут, пока открыта программа, а не
экран. Вернулся — видны процент, пришедшие реплики, текст ответа и его
вкладка; кончилось — экран перечитывает запись сам. Раньше экран
показывал «Расшифровать», хотя ядро ещё работало.
- В меню у записи — метка «расшифровка» / «ИИ», пока идёт работа.
- Кнопка «Записать» из шапки убрана (метка идущей записи осталась).
- Блок «Текст предупреждения участникам» убран из настроек, экрана
«Новая запись» и панели записи.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a730a5c
1 октября 2026 г.
main.ts
// Оболочка. Маршруты: #/ — главная, #/new — новая запись, #/m/<id>[/<вкладка>] — запись, #/settings.
import { renderHome } from "./views/home";
import { renderMeeting } from "./views/meeting";
import { renderNew } from "./views/new";
import { renderSettings } from "./views/settings";
import { startJobs } from "./jobs";
import { refreshNav, setCrumb, startNav } from "./nav";
import { errorText, files } from "./api";
import { esc } from "./dom";
import { Scope } from "./scope";
import { addAudio, onChange, refreshRecording } from "./state";
const main = document.getElementById("app")!;
let scope = new Scope();
async function route(): Promise<void> {
scope.dispose();
scope = new Scope();
const [section, id, tab] = location.hash.replace(/^#\/?/, "").split("/");
main.scrollTop = 0;
setCrumb(null);
void refreshNav();
try {
if (section === "m" && id) {
await renderMeeting(main, scope, decodeURIComponent(id), tab ? decodeURIComponent(tab) : null);
} else if (section === "new") {
await renderNew(main, scope);
} else if (section === "settings") {
await renderSettings(main);
} else {
await renderHome(main, scope);
}
} catch (e) {
main.innerHTML = `<div class="page"><p class="error">${esc(errorText(e))}</p></div>`;
}
}
async function start(): Promise<void> {
await refreshRecording();
startNav();
startJobs();
// Запись началась, встала на паузу или закончилась — шапка и меню меняются.
onChange(() => void refreshNav());
// Аудиофайл, брошенный в окно с любого экрана, — новая запись.
await files.onDrop(async (paths) => {
for (const p of paths) await addAudio(p);
});
window.addEventListener("hashchange", route);
await route();
}
start().catch((e) => {
main.innerHTML = `<p class="error">${esc(errorText(e))}</p>`;
});