Files
ChatAIBot/static/js/contextEditor.js
T
2026-06-04 08:05:06 +03:00

106 lines
4.7 KiB
JavaScript

import { sessionId } from './state.js';
function fmtJson(raw, fallback) {
try {
return JSON.stringify(JSON.parse(raw || fallback), null, 2);
} catch {
return raw || fallback;
}
}
function parseStats(raw) {
try {
return { lust: 0, stamina: 10, tension: 0, ...JSON.parse(raw || '{}') };
} catch {
return { lust: 0, stamina: 10, tension: 0 };
}
}
export async function openContextEditor() {
if (!sessionId) return;
const res = await fetch(`/chat/system/${sessionId}`);
if (!res.ok) return;
const blob = await res.json();
document.getElementById('ctxStatusQuo').value = blob.status_quo || '';
document.getElementById('ctxGlobalPlot').value = blob.global_plot || '';
document.getElementById('ctxOutfit').value = fmtJson(blob.outfit_json, '[]');
document.getElementById('ctxScene').value = fmtJson(blob.scene_json, '{}');
document.getElementById('ctxFacts').value = fmtJson(blob.facts_json, '[]');
document.getElementById('ctxPlotArc').value = fmtJson(blob.plot_arc_json, '{}');
document.getElementById('ctxAffinity').value = String(blob.affinity ?? 0);
const stats = parseStats(blob.narrative_stats_json);
document.getElementById('ctxLust').value = String(stats.lust ?? 0);
document.getElementById('ctxStamina').value = String(stats.stamina ?? 10);
document.getElementById('ctxTension').value = String(stats.tension ?? 0);
const st = document.getElementById('contextEditorStatus');
if (st) {
st.textContent = '';
st.style.color = '';
}
document.getElementById('contextEditorModal')?.classList.add('open');
}
export function initContextEditor() {
document.getElementById('contextEditorOpen')?.addEventListener('click', () => {
openContextEditor();
});
document.getElementById('contextEditorCancel')?.addEventListener('click', () => {
document.getElementById('contextEditorModal')?.classList.remove('open');
});
document.getElementById('contextEditorSave')?.addEventListener('click', async () => {
if (!sessionId) return;
const statusEl = document.getElementById('contextEditorStatus');
const body = {
status_quo: document.getElementById('ctxStatusQuo')?.value ?? '',
global_plot: document.getElementById('ctxGlobalPlot')?.value ?? '',
outfit_json: document.getElementById('ctxOutfit')?.value ?? '[]',
scene_json: document.getElementById('ctxScene')?.value ?? '{}',
facts_json: document.getElementById('ctxFacts')?.value ?? '[]',
plot_arc_json: document.getElementById('ctxPlotArc')?.value ?? '{}',
affinity: Number(document.getElementById('ctxAffinity')?.value ?? 0),
lust: Number(document.getElementById('ctxLust')?.value ?? 0),
stamina: Number(document.getElementById('ctxStamina')?.value ?? 10),
tension: Number(document.getElementById('ctxTension')?.value ?? 0),
};
try {
const res = await fetch(`/sessions/${sessionId}/context`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
if (statusEl) {
statusEl.textContent = err.detail || res.statusText;
statusEl.style.color = '#e74c3c';
}
return;
}
const data = await res.json();
if (data.outfit_json) {
document.getElementById('ctxOutfit').value = fmtJson(data.outfit_json, '[]');
}
const { renderSystemBlob, applySessionUi } = await import('./sessions.js');
const { updateAffinityDisplay, updateStatsDisplay } = await import('./chat.js');
const blobRes = await fetch(`/chat/system/${sessionId}`);
if (blobRes.ok) renderSystemBlob(await blobRes.json());
const sessRes = await fetch(`/sessions/${sessionId}`);
if (sessRes.ok) applySessionUi(await sessRes.json());
if (data.affinity !== undefined) updateAffinityDisplay(data.affinity);
if (data.narrative_stats) updateStatsDisplay(data.narrative_stats);
if (statusEl) {
statusEl.textContent = 'Сохранено (outfit: цвета добавлены автоматически, если не указаны)';
statusEl.style.color = '#2ecc71';
}
} catch {
if (statusEl) {
statusEl.textContent = 'Ошибка сети';
statusEl.style.color = '#e74c3c';
}
}
});
}