feat(submit): add user media library

This commit is contained in:
2026-09-04 22:53:33 +08:00
parent 44e165d34e
commit f3fcfe45da
23 changed files with 1321 additions and 945 deletions
+86 -88
View File
@@ -21,6 +21,15 @@
return Array.prototype.slice.call((root || document).querySelectorAll(sel));
}
function escapeHtml(value) {
return String(value || '')
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
function getEditorContent() {
if (window.tinymce) {
var ed = window.tinymce.get('post_content');
@@ -82,9 +91,10 @@
init: function () {
this.form = document.getElementById('aksrt-submit-form');
if (!this.form) {
if (!this.form || this.form.getAttribute('data-aksrt-submit-ready') === '1') {
return;
}
this.form.setAttribute('data-aksrt-submit-ready', '1');
this.bindDirty();
this.bindAutoHeight();
this.bindSubmitButtons();
@@ -258,19 +268,27 @@
if (d.time) {
var timeEl = qs('.aksrt-submit-modified-time');
if (timeEl) {
timeEl.innerHTML =
'<span class="badg">' + (i18n.lastSaved || 'Last saved: ') + d.time + '</span>';
timeEl.textContent = '';
var timeBadge = document.createElement('span');
timeBadge.className = 'badg';
timeBadge.textContent = (i18n.lastSaved || '最后保存:') + d.time;
timeEl.appendChild(timeBadge);
}
}
if (d.url) {
var view = qs('.aksrt-submit-view-btn');
if (view) {
view.innerHTML =
'<a class="but c-blue" target="_blank" href="' +
d.url +
'"><i class="fa fas fa-file-alt"></i> ' +
(i18n.preview || 'Preview') +
'</a>';
view.textContent = '';
var previewLink = document.createElement('a');
previewLink.className = 'but c-blue';
previewLink.target = '_blank';
previewLink.rel = 'noopener';
previewLink.href = String(d.url);
var previewIcon = document.createElement('i');
previewIcon.className = 'fa fas fa-file-alt';
previewLink.appendChild(previewIcon);
previewLink.appendChild(document.createTextNode(' ' + (i18n.preview || 'Preview')));
view.appendChild(previewLink);
}
}
notyf(
@@ -398,16 +416,16 @@
}
var html = '';
if (t === 'image' && d.url) {
html = '<img src="' + d.url + '" alt="">';
html = '<img src="' + escapeHtml(d.url) + '" alt="">';
} else if (t === 'slide' && Array.isArray(d) && d[0] && d[0].url) {
html =
'<img src="' +
d[0].url +
escapeHtml(d[0].url) +
'" alt=""><span class="featured-type-badge"><i class="fa fas fa-image"></i></span>';
} else if (t === 'video') {
html =
(d.pic
? '<img src="' + d.pic + '" alt="">'
? '<img src="' + escapeHtml(d.pic) + '" alt="">'
: '<div class="featured-video-placeholder"><i class="fa fas fa-play"></i></div>') +
'<span class="featured-type-badge"><i class="fa fas fa-video"></i></span>';
}
@@ -418,41 +436,13 @@
}
},
uploadFile: function (kind, file) {
var upload = (cfg.uploads || {})[kind] || null;
if (!upload || !upload.url || !file) {
return Promise.reject(new Error(i18n.error || 'Upload unavailable'));
openMediaPicker: function (options) {
if (!window.AksrtSubmitMedia || typeof window.AksrtSubmitMedia.open !== 'function') {
notyf(i18n.mediaPickerUnavailable || '媒体选择器加载失败,请刷新页面后重试', 'danger');
return false;
}
if (upload.maxSize && file.size > upload.maxSize) {
return Promise.reject(new Error(i18n.fileTooLarge || '文件大小超过限制'));
}
var body = new FormData();
body.append('file', file);
return fetch(upload.url, {
method: 'POST',
credentials: 'same-origin',
headers: { 'X-WP-Nonce': cfg.restNonce || '' },
body: body,
}).then(function (response) {
return response.json().catch(function () { return {}; }).then(function (payload) {
if (!response.ok || !payload || !payload.success) {
throw new Error((payload && payload.message) || i18n.error || 'Upload failed');
}
return payload;
});
});
},
pickUpload: function (kind, accept) {
return new Promise(function (resolve) {
var input = document.createElement('input');
input.type = 'file';
input.accept = accept;
input.addEventListener('change', function () {
resolve(input.files && input.files[0] ? input.files[0] : null);
}, { once: true });
input.click();
});
window.AksrtSubmitMedia.open(options);
return true;
},
bindFeatured: function () {
@@ -473,54 +463,64 @@
return;
}
if (act === 'image') {
var imageToastId = 'aksrt-front-submit-featured-upload-toast';
self.pickUpload('image', 'image/*').then(function (file) {
if (!file) return null;
notyf(i18n.uploading || '正在上传封面…', 'load', '', imageToastId);
return self.uploadFile('image', file);
}).then(function (file) {
if (!file) return;
self.setFeatured('image', { url: file.url, id: file.attachment_id });
notyf(i18n.uploaded || '封面上传成功', 'success', 5, imageToastId);
}).catch(function (error) {
notyf(error.message || i18n.error || '封面上传失败', 'danger', 5, imageToastId);
self.openMediaPicker({
type: 'image',
multiple: false,
allowExternal: false,
onSelect: function (item) {
if (!item) return;
self.setFeatured('image', { url: item.url || '', id: item.attachment_id || item.id || 0 });
},
});
return;
}
if (act === 'slide') {
var slideToastId = 'aksrt-front-submit-slide-upload-toast';
self.pickUpload('image', 'image/*').then(function (file) {
if (!file) return null;
notyf(i18n.uploading || '正在上传幻灯片封面…', 'load', '', slideToastId);
return self.uploadFile('image', file);
}).then(function (file) {
if (!file) return;
self.setFeatured('slide', [{ url: file.url, id: file.attachment_id }]);
notyf(i18n.uploaded || '幻灯片封面上传成功', 'success', 5, slideToastId);
}).catch(function (error) {
notyf(error.message || i18n.error || '幻灯片封面上传失败', 'danger', 5, slideToastId);
self.openMediaPicker({
type: 'image',
multiple: true,
maxItems: 30,
allowExternal: false,
onSelect: function (items) {
var slides = (Array.isArray(items) ? items : []).map(function (item) {
return { url: item.url || '', id: item.attachment_id || item.id || 0 };
}).filter(function (item) { return item.url || item.id; });
if (slides.length) self.setFeatured('slide', slides);
},
});
return;
}
if (act === 'video') {
var url = window.prompt(i18n.videoUrl || 'Video URL');
if (!url) {
return;
}
var videoToastId = 'aksrt-front-submit-video-cover-toast';
self.pickUpload('image', 'image/*').then(function (file) {
if (!file) {
self.setFeatured('video', { url: url, pic: '' });
return null;
}
notyf(i18n.uploading || '正在上传视频封面…', 'load', '', videoToastId);
return self.uploadFile('image', file);
}).then(function (file) {
if (!file) return;
self.setFeatured('video', { url: url, pic: file.url });
notyf(i18n.uploaded || '视频封面上传成功', 'success', 5, videoToastId);
}).catch(function (error) {
notyf(error.message || i18n.error || '视频封面上传失败', 'danger', 5, videoToastId);
self.openMediaPicker({
type: 'video',
multiple: false,
allowExternal: true,
allowEmbed: false,
onSelect: function (item) {
if (!item || !item.url) return;
var video = {
url: item.url,
pic: '',
pic_id: 0,
id: item.attachment_id || item.id || 0,
};
self.setFeatured('video', video);
window.setTimeout(function () {
self.openMediaPicker({
type: 'image',
multiple: false,
allowExternal: false,
title: i18n.pickVideoCover || '选择视频封面(可选)',
onSelect: function (cover) {
self.setFeatured('video', {
url: video.url,
pic: cover && cover.url ? cover.url : '',
pic_id: cover ? (cover.attachment_id || cover.id || 0) : 0,
id: video.id,
});
},
});
}, 0);
},
});
}
});
@@ -572,8 +572,6 @@
window.aksrtSubmitPayDownloads.init({
root: box,
pickUpload: this.pickUpload.bind(this),
uploadFile: this.uploadFile.bind(this),
notify: notyf,
markDirty: function () {
App.isDirty = true;