refactor(creator-studio): pick the cover from the toolbar image dialog
The cover row carried its own hidden file input and upload call, so authors had two different image flows in one page. - 添加封面 now opens window.JioSubmitMedia with type=image, the same dialog the toolbar's 图片 button uses (mine / upload / external link). - The picked image is stored as the full-size URL plus its attachment id, matching FrontSubmitFeatured's image branch, which re-checks ownership and sets the post thumbnail. - Removes the now-unused uploadCover path, apiUpload/nonce imports, and the .jio-creator__cover-input rule. Contract added; 887 widget-system tests pass.
This commit is contained in:
1 parent
f97fd72bd0
commit
4cd296c066
6 files changed
+58
-61
No files matched your search
@@ -8,10 +8,9 @@
|
||||
* @package Jio
|
||||
*/
|
||||
|
||||
import { useMemo, useRef, useState } from '@wordpress/element';
|
||||
import { useMemo, useState } from '@wordpress/element';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
|
||||
import { apiUpload } from '../services/api';
|
||||
import type { PayState } from '../draft';
|
||||
|
||||
type Featured = { type: string; data: Record<string, any>; mediaId?: number };
|
||||
@@ -78,9 +77,7 @@ export function PublishSettings({
|
||||
onCustomChange,
|
||||
onOpenPaySettings,
|
||||
}: Props) {
|
||||
const coverInput = useRef<HTMLInputElement | null>(null);
|
||||
const [tagInput, setTagInput] = useState('');
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const minSchedule = useMemo(() => toLocalInput(new Date(Date.now() + 5 * 60 * 1000)), []);
|
||||
const coverUrl = typeof featured?.data?.url === 'string' ? featured.data.url : '';
|
||||
@@ -112,30 +109,37 @@ export function PublishSettings({
|
||||
});
|
||||
};
|
||||
|
||||
const uploadCover = async () => {
|
||||
const file = coverInput.current?.files?.[0];
|
||||
const uploadUrl = bootstrap.media?.uploadUrl?.image;
|
||||
if (!file || !uploadUrl) {
|
||||
/**
|
||||
* 复用工具栏「图片」按钮的媒体弹窗选封面。
|
||||
*
|
||||
* 与正文插图走同一个 JioSubmitMedia:可以直接从「我的图片」挑,
|
||||
* 也可以当场上传或填外链,作者不必在两套上传 UI 之间切换。
|
||||
*/
|
||||
const pickCover = () => {
|
||||
const media = (window as any).JioSubmitMedia;
|
||||
if (!media || typeof media.open !== 'function') {
|
||||
setError(__('媒体选择器尚未加载,请刷新页面后重试。', 'jio'));
|
||||
return;
|
||||
}
|
||||
setError('');
|
||||
setUploading(true);
|
||||
try {
|
||||
const response = await apiUpload(uploadUrl, file, nonce);
|
||||
const id = Number(response.attachment_id || response.id || 0);
|
||||
const url = String(response.url || '');
|
||||
if (!id || !url) {
|
||||
throw new Error(__('上传后无法读取图片。', 'jio'));
|
||||
}
|
||||
onFeaturedChange({ type: 'image', mediaId: id, data: { id, url } });
|
||||
} catch (uploadError: any) {
|
||||
setError(String(uploadError?.message || __('上传失败', 'jio')));
|
||||
} finally {
|
||||
setUploading(false);
|
||||
if (coverInput.current) {
|
||||
coverInput.current.value = '';
|
||||
}
|
||||
}
|
||||
media.open({
|
||||
type: 'image',
|
||||
multiple: false,
|
||||
onSelect: (selected: any) => {
|
||||
const item = Array.isArray(selected) ? selected[0] : selected;
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
// 封面按原图保存,预览才用缩略图,避免分享卡片被压成小图。
|
||||
const url = String(item.url || item.large_url || '');
|
||||
if (!url) {
|
||||
setError(__('无法读取图片地址,请重新选择。', 'jio'));
|
||||
return;
|
||||
}
|
||||
const id = Number(item.attachment_id || item.id || 0);
|
||||
onFeaturedChange({ type: 'image', mediaId: id, data: { id, url } });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -245,7 +249,7 @@ export function PublishSettings({
|
||||
<button
|
||||
type="button"
|
||||
className="jio-creator__cover-preview"
|
||||
onClick={() => coverInput.current?.click()}
|
||||
onClick={pickCover}
|
||||
aria-label={__('更换封面', 'jio')}
|
||||
>
|
||||
<img src={coverUrl} alt="" />
|
||||
@@ -260,23 +264,11 @@ export function PublishSettings({
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="jio-creator__cover-add"
|
||||
onClick={() => coverInput.current?.click()}
|
||||
disabled={uploading}
|
||||
>
|
||||
<button type="button" className="jio-creator__cover-add" onClick={pickCover}>
|
||||
<i className="fa fas fa-plus" aria-hidden="true" />
|
||||
<span>{uploading ? __('上传中…', 'jio') : __('添加封面', 'jio')}</span>
|
||||
<span>{__('添加封面', 'jio')}</span>
|
||||
</button>
|
||||
)}
|
||||
<input
|
||||
ref={coverInput}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
className="jio-creator__cover-input"
|
||||
onChange={() => void uploadCover()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -699,15 +699,6 @@ body.jio-page-submit.has-static-nav {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.jio-creator__cover-input {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.jio-creator__cover-add {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in new issue
Block a user