Spaces:
Running
Running
FIX: rewriteArticle calls /api/rewrite_slide (correct endpoint name from rewrite_slide.py)"
Browse files- static/rewrite_fix.js +87 -0
static/rewrite_fix.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Fix rewriteArticle - call correct endpoint
|
| 2 |
+
// This file patches the rewriteArticle function to use /api/rewrite_slide instead of /api/rewrite_share
|
| 3 |
+
|
| 4 |
+
(function(){
|
| 5 |
+
// Override rewriteArticle to call /api/rewrite_slide
|
| 6 |
+
const origRewrite = window.rewriteArticle;
|
| 7 |
+
window.rewriteArticle = async function(){
|
| 8 |
+
const url = _currentArticle?.url;
|
| 9 |
+
if(!url) return;
|
| 10 |
+
toast('⏳ Đang tạo slide tóm tắt...');
|
| 11 |
+
try {
|
| 12 |
+
const r = await fetch('/api/rewrite_slide', {
|
| 13 |
+
method: 'POST',
|
| 14 |
+
headers: {'Content-Type': 'application/json'},
|
| 15 |
+
body: JSON.stringify({url, context: document.querySelector('.article-view')?.innerText?.slice(0,14000) || ''})
|
| 16 |
+
});
|
| 17 |
+
const j = await r.json();
|
| 18 |
+
if (!r.ok || j.error) throw new Error(j.error);
|
| 19 |
+
toast('✅ Đã đăng Tường AI!');
|
| 20 |
+
if (j.post) prependWallPost(j.post);
|
| 21 |
+
// Show slides preview
|
| 22 |
+
if (j.slides && j.slides.length) {
|
| 23 |
+
showSlidePreview(j.slides, j.post?.title || '');
|
| 24 |
+
}
|
| 25 |
+
} catch(e) {
|
| 26 |
+
// Fallback: try /api/rewrite_share (old endpoint from ai_ext)
|
| 27 |
+
try {
|
| 28 |
+
const r2 = await fetch('/api/rewrite_share', {
|
| 29 |
+
method: 'POST',
|
| 30 |
+
headers: {'Content-Type': 'application/json'},
|
| 31 |
+
body: JSON.stringify({url, context: document.querySelector('.article-view')?.innerText?.slice(0,14000) || ''})
|
| 32 |
+
});
|
| 33 |
+
const j2 = await r2.json();
|
| 34 |
+
if (r2.ok && !j2.error) {
|
| 35 |
+
toast('✅ Đã đăng Tường AI!');
|
| 36 |
+
if (j2.post) prependWallPost(j2.post);
|
| 37 |
+
return;
|
| 38 |
+
}
|
| 39 |
+
} catch(e2) {}
|
| 40 |
+
toast('❌ ' + e.message);
|
| 41 |
+
}
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
// Show slides as fullscreen overlay
|
| 45 |
+
window.showSlidePreview = function(slides, title) {
|
| 46 |
+
if (!slides || !slides.length) return;
|
| 47 |
+
const overlay = document.createElement('div');
|
| 48 |
+
overlay.id = 'slide-preview';
|
| 49 |
+
overlay.style.cssText = 'position:fixed;inset:0;background:#000;z-index:99999;display:flex;flex-direction:column;overflow:hidden';
|
| 50 |
+
|
| 51 |
+
let currentSlide = 0;
|
| 52 |
+
function renderSlide(idx) {
|
| 53 |
+
const s = slides[idx];
|
| 54 |
+
overlay.innerHTML = `
|
| 55 |
+
<div style="position:absolute;top:10px;left:10px;right:10px;display:flex;justify-content:space-between;align-items:center;z-index:2">
|
| 56 |
+
<button onclick="document.getElementById('slide-preview').remove()" style="background:rgba(0,0,0,.6);border:0;color:#fff;padding:8px 14px;border-radius:20px;font-size:12px;cursor:pointer">✕ Đóng</button>
|
| 57 |
+
<span style="color:#fff;font-size:11px;background:rgba(0,0,0,.6);padding:4px 10px;border-radius:10px">${idx+1}/${slides.length}</span>
|
| 58 |
+
</div>
|
| 59 |
+
<div style="flex:1;display:flex;align-items:center;justify-content:center;padding:20px">
|
| 60 |
+
${s.image ? `<img src="${esc(s.image)}" style="max-width:100%;max-height:60vh;border-radius:10px;object-fit:contain" onerror="this.style.display='none'">` : ''}
|
| 61 |
+
</div>
|
| 62 |
+
<div style="padding:16px 20px;background:linear-gradient(transparent,rgba(0,0,0,.9));min-height:100px">
|
| 63 |
+
<p style="color:#fff;font-size:14px;line-height:1.6">${esc(s.text)}</p>
|
| 64 |
+
</div>
|
| 65 |
+
<div style="display:flex;gap:10px;padding:10px 20px 20px;justify-content:center">
|
| 66 |
+
<button onclick="prevSlide()" style="background:#333;border:0;color:#fff;padding:10px 20px;border-radius:20px;font-size:12px;cursor:pointer" ${idx===0?'disabled style="opacity:.3"':''}>← Trước</button>
|
| 67 |
+
<button onclick="nextSlide()" style="background:#2d8659;border:0;color:#fff;padding:10px 20px;border-radius:20px;font-size:12px;cursor:pointer" ${idx===slides.length-1?'disabled style="opacity:.3"':''}>Tiếp →</button>
|
| 68 |
+
</div>
|
| 69 |
+
`;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
window.nextSlide = function() { if (currentSlide < slides.length - 1) { currentSlide++; renderSlide(currentSlide); } };
|
| 73 |
+
window.prevSlide = function() { if (currentSlide > 0) { currentSlide--; renderSlide(currentSlide); } };
|
| 74 |
+
|
| 75 |
+
renderSlide(0);
|
| 76 |
+
document.body.appendChild(overlay);
|
| 77 |
+
|
| 78 |
+
// Swipe support
|
| 79 |
+
let startX = 0;
|
| 80 |
+
overlay.addEventListener('touchstart', e => { startX = e.touches[0].clientX; });
|
| 81 |
+
overlay.addEventListener('touchend', e => {
|
| 82 |
+
const diff = e.changedTouches[0].clientX - startX;
|
| 83 |
+
if (diff < -50) nextSlide();
|
| 84 |
+
else if (diff > 50) prevSlide();
|
| 85 |
+
});
|
| 86 |
+
};
|
| 87 |
+
})();
|