feat: update button opens full publish modal, keeps old preview if not changed

This commit is contained in:
2026-07-27 10:51:36 +08:00
parent 2d5cdc0d3b
commit 97de708469
+76 -10
View File
@@ -139,16 +139,7 @@ const PageMarket = {
} }
if (btnUpdate) { if (btnUpdate) {
const input = document.createElement('input'); input.type = 'file'; input.accept = btnUpdate.dataset.type; this._showUpdateModal(btnUpdate.dataset);
input.onchange = async (ev) => {
const file = ev.target.files[0]; if (!file) return;
const fd = new FormData(); fd.append('file', file); fd.append('token', this._marketToken);
const url = btnUpdate.dataset.coll === 'scenes' ? '/api/market/scenes/upload' : '/api/market/upload';
const res = await fetch(url, { method: 'POST', body: fd });
const data = await res.json();
Toast.show(data.error ? '更新失败: ' + data.error : '上传成功(新记录)', data.error ? 'error' : 'success');
if (!data.error) this._loadItems();
}; input.click();
return; return;
} }
if (btnDelete) { if (btnDelete) {
@@ -402,6 +393,81 @@ const PageMarket = {
return `<div class="empty-state" style="grid-column:1/-1"><h4>${msg||'暂无'}</h4></div>`; return `<div class="empty-state" style="grid-column:1/-1"><h4>${msg||'暂无'}</h4></div>`;
}, },
_showUpdateModal(ds) {
if (!this._marketToken) { Toast.show('请先登录', 'error'); return; }
const isScene = ds.coll === 'scenes';
const overlay = document.createElement('div'); overlay.className = 'modal-overlay';
overlay.innerHTML = '<div class="modal" style="min-width:480px;max-width:520px;padding:24px"><h3 style="font-size:18px;font-weight:600;margin-bottom:4px">更新 '+(isScene?'场景':'仪表盘')+'</h3><p style="font-size:12px;color:var(--text-secondary);margin-bottom:18px">重新上传包文件或更换预览图</p><div style="margin-bottom:12px"><label class="switch-label" style="font-size:13px"><input type="checkbox" id="pub-preview-toggle" checked><span class="switch-track"></span> 更换预览图</label></div><button id="pub-update-btn" class="btn btn-primary btn-sm" style="width:100%;margin-bottom:10px">📁 选择新文件 ('+(isScene?'.tss':'.tsd')+')</button><div style="font-size:13px;color:var(--text-tertiary);margin-top:10px;text-align:center">注:仅更新预览图可不选文件</div></div>';
document.body.appendChild(overlay);
overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); });
let updateFile = null, previewFile = null;
const previewDrop = document.createElement('div');
previewDrop.style.cssText = 'border:2px dashed var(--border-normal);border-radius:8px;padding:20px;text-align:center;color:var(--text-tertiary);font-size:13px;cursor:pointer;margin:8px 0;transition:all .2s';
previewDrop.textContent = '点击或拖放新预览图 (最大 6MB)';
overlay.querySelector('.modal').insertBefore(previewDrop, overlay.querySelector('#pub-update-btn'));
function pickPreview() {
const inp = document.createElement('input'); inp.type = 'file'; inp.accept = 'image/*'; inp.style.display = 'none';
inp.onchange = function() {
const f = this.files[0]; if (!f) return;
if (f.size > 6291456) { Toast.show('预览图不能超过 6MB', 'error'); return; }
if (!f.type.startsWith('image/')) { Toast.show('仅支持图片格式', 'error'); return; }
previewFile = f; previewDrop.textContent = '✓ '+f.name+' ('+(f.size/1024/1024).toFixed(1)+' MB)';
previewDrop.style.borderColor = 'var(--accent)'; previewDrop.style.color = 'var(--accent)';
};
document.body.appendChild(inp); inp.click();
}
['dragenter','dragover'].forEach(ev => previewDrop.addEventListener(ev, e => { e.preventDefault(); previewDrop.style.borderColor = 'var(--accent)'; }));
['dragleave','drop'].forEach(ev => previewDrop.addEventListener(ev, e => { e.preventDefault(); previewDrop.style.borderColor = 'var(--border-normal)'; }));
previewDrop.addEventListener('drop', function(e) {
e.preventDefault(); const f = e.dataTransfer.files[0]; if (!f) return;
if (!f.type.startsWith('image/')) { Toast.show('仅支持图片格式', 'error'); return; }
if (f.size > 6291456) { Toast.show('预览图不能超过 6MB', 'error'); return; }
previewFile = f; previewDrop.textContent = '✓ '+f.name+' ('+(f.size/1024/1024).toFixed(1)+' MB)';
previewDrop.style.borderColor = 'var(--accent)'; previewDrop.style.color = 'var(--accent)';
});
previewDrop.addEventListener('click', pickPreview);
overlay.querySelector('#pub-preview-toggle').addEventListener('change', function() {
previewDrop.style.display = this.checked ? '' : 'none';
if (!this.checked) { previewFile = null; previewDrop.textContent = '点击或拖放新预览图 (最大 6MB)'; previewDrop.style.borderColor = 'var(--border-normal)'; previewDrop.style.color = 'var(--text-tertiary)'; }
});
overlay.querySelector('#pub-update-btn').addEventListener('click', () => {
const input = document.createElement('input'); input.type = 'file'; input.accept = isScene ? '.tss' : '.tsd';
input.onchange = function(e) { updateFile = e.target.files[0]; if (updateFile) { const btn = overlay.querySelector('#pub-update-btn'); btn.textContent = '✓ '+updateFile.name; btn.style.background = 'var(--accent)'; btn.style.color = '#fff'; } };
input.click();
});
overlay.querySelector('#pub-update-btn').insertAdjacentHTML('afterend', '<button id="pub-do-update" class="btn btn-primary btn-sm" style="width:100%;margin-top:10px">确认更新</button>');
overlay.querySelector('#pub-do-update').addEventListener('click', async () => {
if (!updateFile && !previewFile) { Toast.show('请选择文件或预览图', 'error'); return; }
const fd = new FormData(); fd.append('token', this._marketToken);
if (updateFile) fd.append('file', updateFile);
if (previewFile) fd.append('preview', previewFile);
// If no new preview given, fetch old one from record
if (!previewFile && ds.preview) {
try {
const prevRes = await fetch('https://turbosu.yeij.top/api/files/'+ds.coll+'/'+ds.id+'/'+ds.preview);
if (prevRes.ok) {
const blob = await prevRes.blob();
fd.append('preview', blob, ds.preview);
}
} catch(e) {}
}
const url = isScene ? '/api/market/scenes/upload' : '/api/market/upload';
const res = await fetch(url, { method: 'POST', body: fd });
const data = await res.json();
if (!data.error && data.id) {
// Delete old record
await fetch('/api/market/delete', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({id: ds.id, collection: ds.coll, token: this._marketToken}) });
}
Toast.show(data.error ? '更新失败: '+data.error : '更新成功', data.error ? 'error' : 'success');
if (!data.error) { overlay.remove(); this._loadItems(); }
});
},
_template() { _template() {
return `<div class="animated"> return `<div class="animated">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:10px"> <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:10px">