feat: update button opens full publish modal, keeps old preview if not changed
This commit is contained in:
+76
-10
@@ -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">
|
||||||
|
|||||||
Reference in New Issue
Block a user