fix: AI review loading UX and Gate preview snapshot time filter SQL

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-05 13:51:16 +08:00
parent 86a6081090
commit 4ac4c062e0
8 changed files with 264 additions and 36 deletions
+48 -8
View File
@@ -232,7 +232,7 @@
.stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px}
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
</style>
<link rel="stylesheet" href="/static/instance_theme.css?v=6">
<link rel="stylesheet" href="/static/instance_theme.css?v=7">
</head>
<body data-page="{{ page }}">
@@ -813,11 +813,11 @@
</div>
<div class="form-row">
<input type="date" id="day_date">
<button type="button" onclick="genDaily()">生成日复盘</button>
<button type="button" id="gen-daily-btn" onclick="genDaily()">生成日复盘</button>
<button type="button" onclick="exportDailyBundleMd()" style="background:#1f3a5a">导出当日日复盘MD</button>
<input type="date" id="week_start">
<input type="date" id="week_end">
<button type="button" onclick="genWeekly()">生成周复盘</button>
<button type="button" id="gen-weekly-btn" onclick="genWeekly()">生成周复盘</button>
<button type="button" onclick="exportWeeklyBundleMd()" style="background:#1f3a5a">导出当周复盘MD</button>
</div>
<div class="ai-result-wrap" id="daily_result_wrap" style="display:none">
@@ -902,7 +902,7 @@
</div>
<script src="/static/instance_ui.js?v=1"></script>
<script src="/static/ai_review_render.js?v=1"></script>
<script src="/static/ai_review_render.js?v=2"></script>
<script src="/static/form_submit_guard.js?v=2"></script>
<script>
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
@@ -1233,36 +1233,76 @@ function loadReviews(){
}
function genDaily(){
if(window.AiReviewRender && AiReviewRender.isGenerating && AiReviewRender.isGenerating()) return;
const d = document.getElementById("day_date").value;
if(!d){alert("请选择日期");return;}
if(window.AiReviewRender && AiReviewRender.setGenerating){
AiReviewRender.setGenerating({
wrapId:"daily_result_wrap",
elId:"daily_result",
btnId:"gen-daily-btn",
message:"生成日复盘中,请稍候…(AI 分析可能需要 1~3 分钟)",
btnLabel:"日复盘生成中…"
});
}
fetch("/ai_daily_review",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`date=${encodeURIComponent(d)}`})
.then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(data=>{
if(!data || data.result == null) throw new Error("返回数据为空");
const el=document.getElementById("daily_result");
const wrap=document.getElementById("daily_result_wrap");
setAiReviewMarkdown(el, data.result);
if(wrap){ wrap.style.display="block"; }
else { el.style.display="block"; }
else if(el){ el.style.display="block"; }
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-daily-btn");
loadReviews();
})
.catch(e=>alert("生成日复盘失败:"+(e.message||e)));
.catch(e=>{
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-daily-btn");
const el=document.getElementById("daily_result");
if(el){
el.classList.remove("is-loading","ai-result-md");
el.innerText="生成失败,请重试。";
}
alert("生成日复盘失败:"+(e.message||e));
});
}
function genWeekly(){
if(window.AiReviewRender && AiReviewRender.isGenerating && AiReviewRender.isGenerating()) return;
const s=document.getElementById("week_start").value;
const e=document.getElementById("week_end").value;
if(!s || !e){alert("请选择起止日期");return;}
if(window.AiReviewRender && AiReviewRender.setGenerating){
AiReviewRender.setGenerating({
wrapId:"weekly_result_wrap",
elId:"weekly_result",
btnId:"gen-weekly-btn",
message:"生成周复盘中,请稍候…(AI 分析可能需要 1~3 分钟)",
btnLabel:"周复盘生成中…"
});
}
fetch("/ai_weekly_review",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`start_date=${encodeURIComponent(s)}&end_date=${encodeURIComponent(e)}`})
.then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(data=>{
if(!data || data.result == null) throw new Error("返回数据为空");
const el=document.getElementById("weekly_result");
const wrap=document.getElementById("weekly_result_wrap");
setAiReviewMarkdown(el, data.result);
if(wrap){ wrap.style.display="block"; }
else { el.style.display="block"; }
else if(el){ el.style.display="block"; }
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-weekly-btn");
loadReviews();
})
.catch(e=>alert("生成周复盘失败:"+(e.message||e)));
.catch(e=>{
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-weekly-btn");
const el=document.getElementById("weekly_result");
if(el){
el.classList.remove("is-loading","ai-result-md");
el.innerText="生成失败,请重试。";
}
alert("生成周复盘失败:"+(e.message||e));
});
}
function exportDailyBundleMd(){
+48 -8
View File
@@ -232,7 +232,7 @@
.stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px}
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
</style>
<link rel="stylesheet" href="/static/instance_theme.css?v=6">
<link rel="stylesheet" href="/static/instance_theme.css?v=7">
</head>
<body data-page="{{ page }}">
@@ -813,11 +813,11 @@
</div>
<div class="form-row">
<input type="date" id="day_date">
<button type="button" onclick="genDaily()">生成日复盘</button>
<button type="button" id="gen-daily-btn" onclick="genDaily()">生成日复盘</button>
<button type="button" onclick="exportDailyBundleMd()" style="background:#1f3a5a">导出当日日复盘MD</button>
<input type="date" id="week_start">
<input type="date" id="week_end">
<button type="button" onclick="genWeekly()">生成周复盘</button>
<button type="button" id="gen-weekly-btn" onclick="genWeekly()">生成周复盘</button>
<button type="button" onclick="exportWeeklyBundleMd()" style="background:#1f3a5a">导出当周复盘MD</button>
</div>
<div class="ai-result-wrap" id="daily_result_wrap" style="display:none">
@@ -902,7 +902,7 @@
</div>
<script src="/static/instance_ui.js?v=1"></script>
<script src="/static/ai_review_render.js?v=1"></script>
<script src="/static/ai_review_render.js?v=2"></script>
<script src="/static/form_submit_guard.js?v=2"></script>
<script>
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
@@ -1233,36 +1233,76 @@ function loadReviews(){
}
function genDaily(){
if(window.AiReviewRender && AiReviewRender.isGenerating && AiReviewRender.isGenerating()) return;
const d = document.getElementById("day_date").value;
if(!d){alert("请选择日期");return;}
if(window.AiReviewRender && AiReviewRender.setGenerating){
AiReviewRender.setGenerating({
wrapId:"daily_result_wrap",
elId:"daily_result",
btnId:"gen-daily-btn",
message:"生成日复盘中,请稍候…(AI 分析可能需要 1~3 分钟)",
btnLabel:"日复盘生成中…"
});
}
fetch("/ai_daily_review",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`date=${encodeURIComponent(d)}`})
.then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(data=>{
if(!data || data.result == null) throw new Error("返回数据为空");
const el=document.getElementById("daily_result");
const wrap=document.getElementById("daily_result_wrap");
setAiReviewMarkdown(el, data.result);
if(wrap){ wrap.style.display="block"; }
else { el.style.display="block"; }
else if(el){ el.style.display="block"; }
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-daily-btn");
loadReviews();
})
.catch(e=>alert("生成日复盘失败:"+(e.message||e)));
.catch(e=>{
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-daily-btn");
const el=document.getElementById("daily_result");
if(el){
el.classList.remove("is-loading","ai-result-md");
el.innerText="生成失败,请重试。";
}
alert("生成日复盘失败:"+(e.message||e));
});
}
function genWeekly(){
if(window.AiReviewRender && AiReviewRender.isGenerating && AiReviewRender.isGenerating()) return;
const s=document.getElementById("week_start").value;
const e=document.getElementById("week_end").value;
if(!s || !e){alert("请选择起止日期");return;}
if(window.AiReviewRender && AiReviewRender.setGenerating){
AiReviewRender.setGenerating({
wrapId:"weekly_result_wrap",
elId:"weekly_result",
btnId:"gen-weekly-btn",
message:"生成周复盘中,请稍候…(AI 分析可能需要 1~3 分钟)",
btnLabel:"周复盘生成中…"
});
}
fetch("/ai_weekly_review",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`start_date=${encodeURIComponent(s)}&end_date=${encodeURIComponent(e)}`})
.then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(data=>{
if(!data || data.result == null) throw new Error("返回数据为空");
const el=document.getElementById("weekly_result");
const wrap=document.getElementById("weekly_result_wrap");
setAiReviewMarkdown(el, data.result);
if(wrap){ wrap.style.display="block"; }
else { el.style.display="block"; }
else if(el){ el.style.display="block"; }
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-weekly-btn");
loadReviews();
})
.catch(e=>alert("生成周复盘失败:"+(e.message||e)));
.catch(e=>{
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-weekly-btn");
const el=document.getElementById("weekly_result");
if(el){
el.classList.remove("is-loading","ai-result-md");
el.innerText="生成失败,请重试。";
}
alert("生成周复盘失败:"+(e.message||e));
});
}
function exportDailyBundleMd(){
+3 -2
View File
@@ -5573,9 +5573,10 @@ def render_main_page(page="trade"):
preview_snapshots = []
if page == "records":
try:
snap_ts = sql_list_time_field("preview_created_at", "snapshot_at")
snap_rows = conn.execute(
f"SELECT * FROM trend_pullback_preview_snapshots WHERE {sql_list_time_field('preview_created_at')} >= ? "
f"AND {sql_list_time_field('preview_created_at')} <= ? ORDER BY id DESC LIMIT 500",
f"SELECT * FROM trend_pullback_preview_snapshots WHERE {snap_ts} >= ? "
f"AND {snap_ts} <= ? ORDER BY id DESC LIMIT 500",
(start_bj, end_bj),
).fetchall()
for sr in snap_rows:
+48 -8
View File
@@ -269,7 +269,7 @@
.stats-split-row{grid-template-columns:1fr}
}
</style>
<link rel="stylesheet" href="/static/instance_theme.css?v=6">
<link rel="stylesheet" href="/static/instance_theme.css?v=7">
</head>
<body data-page="{{ page }}">
@@ -769,11 +769,11 @@
</div>
<div class="form-row">
<input type="date" id="day_date">
<button type="button" onclick="genDaily()">生成日复盘</button>
<button type="button" id="gen-daily-btn" onclick="genDaily()">生成日复盘</button>
<button type="button" onclick="exportDailyBundleMd()" style="background:#1f3a5a">导出当日日复盘MD</button>
<input type="date" id="week_start">
<input type="date" id="week_end">
<button type="button" onclick="genWeekly()">生成周复盘</button>
<button type="button" id="gen-weekly-btn" onclick="genWeekly()">生成周复盘</button>
<button type="button" onclick="exportWeeklyBundleMd()" style="background:#1f3a5a">导出当周复盘MD</button>
</div>
<div class="ai-result-wrap" id="daily_result_wrap" style="display:none">
@@ -871,7 +871,7 @@
</div>
<script src="/static/instance_ui.js?v=1"></script>
<script src="/static/ai_review_render.js?v=1"></script>
<script src="/static/ai_review_render.js?v=2"></script>
<script src="/static/form_submit_guard.js?v=2"></script>
<script>
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
@@ -1196,36 +1196,76 @@ function loadReviews(){
}
function genDaily(){
if(window.AiReviewRender && AiReviewRender.isGenerating && AiReviewRender.isGenerating()) return;
const d = document.getElementById("day_date").value;
if(!d){alert("请选择日期");return;}
if(window.AiReviewRender && AiReviewRender.setGenerating){
AiReviewRender.setGenerating({
wrapId:"daily_result_wrap",
elId:"daily_result",
btnId:"gen-daily-btn",
message:"生成日复盘中,请稍候…(AI 分析可能需要 1~3 分钟)",
btnLabel:"日复盘生成中…"
});
}
fetch("/ai_daily_review",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`date=${encodeURIComponent(d)}`})
.then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(data=>{
if(!data || data.result == null) throw new Error("返回数据为空");
const el=document.getElementById("daily_result");
const wrap=document.getElementById("daily_result_wrap");
setAiReviewMarkdown(el, data.result);
if(wrap){ wrap.style.display="block"; }
else { el.style.display="block"; }
else if(el){ el.style.display="block"; }
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-daily-btn");
loadReviews();
})
.catch(e=>alert("生成日复盘失败:"+(e.message||e)));
.catch(e=>{
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-daily-btn");
const el=document.getElementById("daily_result");
if(el){
el.classList.remove("is-loading","ai-result-md");
el.innerText="生成失败,请重试。";
}
alert("生成日复盘失败:"+(e.message||e));
});
}
function genWeekly(){
if(window.AiReviewRender && AiReviewRender.isGenerating && AiReviewRender.isGenerating()) return;
const s=document.getElementById("week_start").value;
const e=document.getElementById("week_end").value;
if(!s || !e){alert("请选择起止日期");return;}
if(window.AiReviewRender && AiReviewRender.setGenerating){
AiReviewRender.setGenerating({
wrapId:"weekly_result_wrap",
elId:"weekly_result",
btnId:"gen-weekly-btn",
message:"生成周复盘中,请稍候…(AI 分析可能需要 1~3 分钟)",
btnLabel:"周复盘生成中…"
});
}
fetch("/ai_weekly_review",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`start_date=${encodeURIComponent(s)}&end_date=${encodeURIComponent(e)}`})
.then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(data=>{
if(!data || data.result == null) throw new Error("返回数据为空");
const el=document.getElementById("weekly_result");
const wrap=document.getElementById("weekly_result_wrap");
setAiReviewMarkdown(el, data.result);
if(wrap){ wrap.style.display="block"; }
else { el.style.display="block"; }
else if(el){ el.style.display="block"; }
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-weekly-btn");
loadReviews();
})
.catch(e=>alert("生成周复盘失败:"+(e.message||e)));
.catch(e=>{
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-weekly-btn");
const el=document.getElementById("weekly_result");
if(el){
el.classList.remove("is-loading","ai-result-md");
el.innerText="生成失败,请重试。";
}
alert("生成周复盘失败:"+(e.message||e));
});
}
function exportDailyBundleMd(){
+48 -8
View File
@@ -232,7 +232,7 @@
.stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px}
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
</style>
<link rel="stylesheet" href="/static/instance_theme.css?v=6">
<link rel="stylesheet" href="/static/instance_theme.css?v=7">
</head>
<body data-page="{{ page }}">
@@ -822,11 +822,11 @@
</div>
<div class="form-row">
<input type="date" id="day_date">
<button type="button" onclick="genDaily()">生成日复盘</button>
<button type="button" id="gen-daily-btn" onclick="genDaily()">生成日复盘</button>
<button type="button" onclick="exportDailyBundleMd()" style="background:#1f3a5a">导出当日日复盘MD</button>
<input type="date" id="week_start">
<input type="date" id="week_end">
<button type="button" onclick="genWeekly()">生成周复盘</button>
<button type="button" id="gen-weekly-btn" onclick="genWeekly()">生成周复盘</button>
<button type="button" onclick="exportWeeklyBundleMd()" style="background:#1f3a5a">导出当周复盘MD</button>
</div>
<div class="ai-result-wrap" id="daily_result_wrap" style="display:none">
@@ -911,7 +911,7 @@
</div>
<script src="/static/instance_ui.js?v=1"></script>
<script src="/static/ai_review_render.js?v=1"></script>
<script src="/static/ai_review_render.js?v=2"></script>
<script src="/static/form_submit_guard.js?v=2"></script>
<script>
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
@@ -1242,36 +1242,76 @@ function loadReviews(){
}
function genDaily(){
if(window.AiReviewRender && AiReviewRender.isGenerating && AiReviewRender.isGenerating()) return;
const d = document.getElementById("day_date").value;
if(!d){alert("请选择日期");return;}
if(window.AiReviewRender && AiReviewRender.setGenerating){
AiReviewRender.setGenerating({
wrapId:"daily_result_wrap",
elId:"daily_result",
btnId:"gen-daily-btn",
message:"生成日复盘中,请稍候…(AI 分析可能需要 1~3 分钟)",
btnLabel:"日复盘生成中…"
});
}
fetch("/ai_daily_review",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`date=${encodeURIComponent(d)}`})
.then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(data=>{
if(!data || data.result == null) throw new Error("返回数据为空");
const el=document.getElementById("daily_result");
const wrap=document.getElementById("daily_result_wrap");
setAiReviewMarkdown(el, data.result);
if(wrap){ wrap.style.display="block"; }
else { el.style.display="block"; }
else if(el){ el.style.display="block"; }
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-daily-btn");
loadReviews();
})
.catch(e=>alert("生成日复盘失败:"+(e.message||e)));
.catch(e=>{
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-daily-btn");
const el=document.getElementById("daily_result");
if(el){
el.classList.remove("is-loading","ai-result-md");
el.innerText="生成失败,请重试。";
}
alert("生成日复盘失败:"+(e.message||e));
});
}
function genWeekly(){
if(window.AiReviewRender && AiReviewRender.isGenerating && AiReviewRender.isGenerating()) return;
const s=document.getElementById("week_start").value;
const e=document.getElementById("week_end").value;
if(!s || !e){alert("请选择起止日期");return;}
if(window.AiReviewRender && AiReviewRender.setGenerating){
AiReviewRender.setGenerating({
wrapId:"weekly_result_wrap",
elId:"weekly_result",
btnId:"gen-weekly-btn",
message:"生成周复盘中,请稍候…(AI 分析可能需要 1~3 分钟)",
btnLabel:"周复盘生成中…"
});
}
fetch("/ai_weekly_review",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`start_date=${encodeURIComponent(s)}&end_date=${encodeURIComponent(e)}`})
.then(r=>{ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(data=>{
if(!data || data.result == null) throw new Error("返回数据为空");
const el=document.getElementById("weekly_result");
const wrap=document.getElementById("weekly_result_wrap");
setAiReviewMarkdown(el, data.result);
if(wrap){ wrap.style.display="block"; }
else { el.style.display="block"; }
else if(el){ el.style.display="block"; }
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-weekly-btn");
loadReviews();
})
.catch(e=>alert("生成周复盘失败:"+(e.message||e)));
.catch(e=>{
if(window.AiReviewRender && AiReviewRender.clearGenerating) AiReviewRender.clearGenerating("gen-weekly-btn");
const el=document.getElementById("weekly_result");
if(el){
el.classList.remove("is-loading","ai-result-md");
el.innerText="生成失败,请重试。";
}
alert("生成周复盘失败:"+(e.message||e));
});
}
function exportDailyBundleMd(){
+7 -2
View File
@@ -92,9 +92,14 @@ def sql_list_time_field(*columns):
"""
SQLite 列表时间窗比较表达式
journal_entries open/close 可能含 'T'直接与 bounds空格格式比会误判为超出上界
单列时不用 COALESCESQLite 要求 COALESCE 至少 2 个参数
"""
cols = ", ".join(columns)
return f"REPLACE(COALESCE({cols}), 'T', ' ')"
cols = [c for c in columns if c]
if not cols:
raise ValueError("sql_list_time_field requires at least one column")
if len(cols) == 1:
return f"REPLACE({cols[0]}, 'T', ' ')"
return f"REPLACE(COALESCE({', '.join(cols)}), 'T', ' ')"
SESSION_KEY_LIST_WIN = "list_win_filter"
+47
View File
@@ -109,10 +109,54 @@
return html.join("\n");
}
var _genBusy = false;
function setGenerating(opts) {
opts = opts || {};
_genBusy = true;
var wrap = document.getElementById(opts.wrapId);
var el = document.getElementById(opts.elId);
var btn = opts.btnId ? document.getElementById(opts.btnId) : null;
if (wrap) wrap.style.display = "block";
if (el) {
el.classList.remove("ai-result-md");
el.classList.add("is-loading");
el.innerHTML = "";
el.innerText = opts.message || "生成复盘中,请稍候…";
}
if (btn) {
btn.disabled = true;
if (!btn.dataset.aiOrigText) btn.dataset.aiOrigText = btn.textContent;
btn.textContent = opts.btnLabel || "生成中…";
}
if (wrap && wrap.scrollIntoView) {
try {
wrap.scrollIntoView({ behavior: "smooth", block: "nearest" });
} catch (e) { /* ignore */ }
}
}
function clearGenerating(btnId) {
_genBusy = false;
var btn = btnId ? document.getElementById(btnId) : null;
if (btn) {
btn.disabled = false;
if (btn.dataset.aiOrigText) {
btn.textContent = btn.dataset.aiOrigText;
delete btn.dataset.aiOrigText;
}
}
}
function isGenerating() {
return _genBusy;
}
function setElementMarkdown(el, rawText) {
if (!el) return;
var raw = String(rawText || "");
el.dataset.markdownRaw = raw;
el.classList.remove("is-loading");
el.classList.add("ai-result-md");
el.innerHTML = renderMarkdown(raw);
}
@@ -130,5 +174,8 @@
renderMarkdown: renderMarkdown,
setElementMarkdown: setElementMarkdown,
getElementMarkdown: getElementMarkdown,
setGenerating: setGenerating,
clearGenerating: clearGenerating,
isGenerating: isGenerating,
};
})(typeof window !== "undefined" ? window : this);
+15
View File
@@ -601,6 +601,21 @@ html[data-theme="light"] .ai-result {
color: #1a2838 !important;
}
.ai-result.is-loading {
color: #8fc8ff;
font-style: italic;
animation: ai-review-pulse 1.2s ease-in-out infinite;
}
html[data-theme="light"] .ai-result.is-loading {
color: #006e9a !important;
}
@keyframes ai-review-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.55; }
}
html[data-theme="light"] .ai-result-md p,
html[data-theme="light"] .detail-modal .panel-body.md-review p {
color: #1a2838 !important;