fix: 对齐 postid 参考图工作台行为
This commit is contained in:
1 parent
708cd79f48
commit
8762c3816b
9 files changed
+260
-85
No files matched your search
@@ -1150,31 +1150,58 @@ async def public_imagine_workbench_edit(data: ImagineWorkbenchEditRequest, reque
|
||||
]
|
||||
|
||||
if effective_reference_items:
|
||||
for item in effective_reference_items:
|
||||
ref_parent = _extract_parent_post_id_from_url(str(item.get("parent_post_id") or ""))
|
||||
if ref_parent and not str(item.get("source_image_url") or "").strip():
|
||||
item["parent_post_id"] = ref_parent
|
||||
item["source_image_url"] = await _canonicalize_parent_source_image_url(
|
||||
token,
|
||||
ref_parent,
|
||||
str(item.get("image_url") or "").strip(),
|
||||
)
|
||||
if not str(item.get("image_url") or "").strip():
|
||||
item["image_url"] = item["source_image_url"]
|
||||
|
||||
result = await edit_service.edit_with_reference_items(
|
||||
token_mgr=token_mgr,
|
||||
token=token,
|
||||
model_info=model_info,
|
||||
prompt=prompt,
|
||||
reference_items=effective_reference_items,
|
||||
root_parent_post_id=parent_post_id if use_parent_mode else "",
|
||||
response_format="url",
|
||||
stream=False,
|
||||
return_all_images=True,
|
||||
progress_cb=progress_cb,
|
||||
first_ref = effective_reference_items[0] if effective_reference_items else {}
|
||||
only_single_parent_ref = (
|
||||
len(effective_reference_items) == 1
|
||||
and bool(str(first_ref.get("parent_post_id") or "").strip())
|
||||
)
|
||||
mode = "parent_post" if use_parent_mode else "upload"
|
||||
if only_single_parent_ref:
|
||||
single_parent_post_id = str(first_ref.get("parent_post_id") or "").strip()
|
||||
single_source_image_url = str(
|
||||
first_ref.get("source_image_url")
|
||||
or first_ref.get("image_url")
|
||||
or current_source_image_url_input
|
||||
or ""
|
||||
).strip()
|
||||
result = await edit_service.edit_with_parent_post(
|
||||
token_mgr=token_mgr,
|
||||
token=token,
|
||||
model_info=model_info,
|
||||
prompt=prompt,
|
||||
parent_post_id=single_parent_post_id,
|
||||
source_image_url=single_source_image_url,
|
||||
response_format="url",
|
||||
stream=False,
|
||||
return_all_images=True,
|
||||
progress_cb=progress_cb,
|
||||
)
|
||||
mode = "parent_post"
|
||||
else:
|
||||
for item in effective_reference_items:
|
||||
ref_parent = _extract_parent_post_id_from_url(str(item.get("parent_post_id") or ""))
|
||||
if ref_parent and not str(item.get("source_image_url") or "").strip():
|
||||
item["parent_post_id"] = ref_parent
|
||||
item["source_image_url"] = await _canonicalize_parent_source_image_url(
|
||||
token,
|
||||
ref_parent,
|
||||
str(item.get("image_url") or "").strip(),
|
||||
)
|
||||
if not str(item.get("image_url") or "").strip():
|
||||
item["image_url"] = item["source_image_url"]
|
||||
|
||||
result = await edit_service.edit_with_reference_items(
|
||||
token_mgr=token_mgr,
|
||||
token=token,
|
||||
model_info=model_info,
|
||||
prompt=prompt,
|
||||
reference_items=effective_reference_items,
|
||||
root_parent_post_id=parent_post_id if use_parent_mode else "",
|
||||
response_format="url",
|
||||
stream=False,
|
||||
return_all_images=True,
|
||||
progress_cb=progress_cb,
|
||||
)
|
||||
mode = "parent_post" if use_parent_mode else "upload"
|
||||
elif use_parent_mode:
|
||||
if current_source_image_url_input and not (
|
||||
current_source_image_url_input.startswith("http://")
|
||||
|
||||
@@ -362,14 +362,17 @@ async def public_video_start(data: VideoStartRequest):
|
||||
raise HTTPException(status_code=400, detail="最多支持 7 张参考图")
|
||||
parent_post_refs = [item for item in reference_items if item.get("parent_post_id")]
|
||||
parent_post_id = str(parent_post_refs[0].get("parent_post_id") or "").strip() if parent_post_refs else ""
|
||||
# 带 parent_post_id 的参考项按“基于已有 post 引用”处理,不再同时抽取 image_url,
|
||||
# 避免单个 reference_item 既有 parent_post_id 又有 image_url 时被误判为冲突参数。
|
||||
pure_image_refs = [item for item in reference_items if not item.get("parent_post_id")]
|
||||
image_url = (
|
||||
str(reference_items[0].get("image_url") or "").strip() or None
|
||||
if reference_items
|
||||
str(pure_image_refs[0].get("image_url") or "").strip() or None
|
||||
if pure_image_refs
|
||||
else None
|
||||
)
|
||||
source_image_url = (
|
||||
str(reference_items[0].get("source_image_url") or "").strip() or None
|
||||
if reference_items
|
||||
str(pure_image_refs[0].get("source_image_url") or "").strip() or None
|
||||
if pure_image_refs
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
@@ -772,6 +772,7 @@ class ImageEditService:
|
||||
) -> List[dict[str, str]]:
|
||||
prepared: List[dict[str, str]] = []
|
||||
upload_service = UploadService()
|
||||
primary_parent_consumed = False
|
||||
try:
|
||||
for item in reference_items:
|
||||
raw_source = str(
|
||||
@@ -794,13 +795,23 @@ class ImageEditService:
|
||||
attachment_id = ""
|
||||
resolved_url = ""
|
||||
resolved_id = ""
|
||||
current_parent_post_id = str(item.get("parent_post_id") or "").strip()
|
||||
should_upload_for_attachment = _needs_image_edit_reference_upload(
|
||||
item, raw_source
|
||||
)
|
||||
if current_parent_post_id:
|
||||
if not primary_parent_consumed:
|
||||
primary_parent_consumed = True
|
||||
should_upload_for_attachment = False
|
||||
else:
|
||||
should_upload_for_attachment = True
|
||||
if not should_upload_for_attachment:
|
||||
normalized_raw = _normalize_asset_url(raw_source)
|
||||
if normalized_raw and not _is_assets_content_url(normalized_raw):
|
||||
should_upload_for_attachment = True
|
||||
if current_parent_post_id and primary_parent_consumed:
|
||||
should_upload_for_attachment = False
|
||||
else:
|
||||
should_upload_for_attachment = True
|
||||
if should_upload_for_attachment:
|
||||
file_id, file_uri = await upload_service.upload_file(raw_source, token)
|
||||
resolved_url = _normalize_asset_url(file_uri)
|
||||
@@ -808,10 +819,7 @@ class ImageEditService:
|
||||
resolved_url
|
||||
)
|
||||
attachment_id = str(file_id or "").strip() or resolved_id
|
||||
if raw_source.startswith("http://") or raw_source.startswith("https://"):
|
||||
request_url = raw_source
|
||||
else:
|
||||
request_url = resolved_url
|
||||
request_url = resolved_url
|
||||
mention_id = resolved_id or mention_id
|
||||
else:
|
||||
if raw_source.startswith("/users/") or raw_source.startswith("users/"):
|
||||
@@ -821,7 +829,7 @@ class ImageEditService:
|
||||
resolved_url = _normalize_asset_url(raw_source)
|
||||
resolved_id = _extract_image_post_id(resolved_url)
|
||||
mention_id = mention_id or resolved_id
|
||||
attachment_id = resolved_id
|
||||
attachment_id = ""
|
||||
prepared.append(
|
||||
{
|
||||
"source_url": raw_source,
|
||||
@@ -831,7 +839,7 @@ class ImageEditService:
|
||||
"resolved_id": resolved_id,
|
||||
"mention_id": mention_id,
|
||||
"attachment_id": attachment_id,
|
||||
"parent_post_id": str(item.get("parent_post_id") or "").strip(),
|
||||
"parent_post_id": current_parent_post_id if not should_upload_for_attachment else "",
|
||||
"mention_alias": mention_alias,
|
||||
}
|
||||
)
|
||||
@@ -917,19 +925,9 @@ class ImageEditService:
|
||||
if str(item.get("request_url") or item.get("resolved_url") or "").strip()
|
||||
]
|
||||
file_attachments = [
|
||||
str(
|
||||
item.get("attachment_id")
|
||||
or item.get("resolved_id")
|
||||
or item.get("mention_id")
|
||||
or ""
|
||||
).strip()
|
||||
str(item.get("attachment_id") or "").strip()
|
||||
for item in prepared_refs
|
||||
if str(
|
||||
item.get("attachment_id")
|
||||
or item.get("resolved_id")
|
||||
or item.get("mention_id")
|
||||
or ""
|
||||
).strip()
|
||||
if str(item.get("attachment_id") or "").strip()
|
||||
]
|
||||
if not request_urls:
|
||||
raise AppException(
|
||||
@@ -939,17 +937,23 @@ class ImageEditService:
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
effective_parent_post_id = str(root_parent_post_id or "").strip()
|
||||
if not effective_parent_post_id:
|
||||
first_parent = str(
|
||||
prepared_refs[0].get("parent_post_id") or ""
|
||||
).strip()
|
||||
if first_parent:
|
||||
effective_parent_post_id = first_parent
|
||||
if not effective_parent_post_id:
|
||||
effective_parent_post_id = await VideoService().create_image_post(
|
||||
current_token, request_urls[0]
|
||||
)
|
||||
parent_ids = [
|
||||
str(item.get("parent_post_id") or "").strip()
|
||||
for item in prepared_refs
|
||||
if str(item.get("parent_post_id") or "").strip()
|
||||
]
|
||||
unique_parent_ids = list(dict.fromkeys(parent_ids))
|
||||
effective_parent_post_id = ""
|
||||
# 多张不同 parentPostId 的参考图不能再强行指定单个 parentPostId,
|
||||
# 否则上游会把它视为互相冲突的编辑上下文并直接返回 400。
|
||||
if len(unique_parent_ids) == 1:
|
||||
effective_parent_post_id = unique_parent_ids[0]
|
||||
elif not unique_parent_ids:
|
||||
effective_parent_post_id = str(root_parent_post_id or "").strip()
|
||||
if not effective_parent_post_id:
|
||||
effective_parent_post_id = await VideoService().create_image_post(
|
||||
current_token, request_urls[0]
|
||||
)
|
||||
|
||||
await self._emit_progress(
|
||||
progress_cb, "chat_request_start", 42, "已提交编辑请求"
|
||||
@@ -960,10 +964,13 @@ class ImageEditService:
|
||||
"imageEditModel": "imagine",
|
||||
"imageEditModelConfig": {
|
||||
"imageReferences": request_urls,
|
||||
"parentPostId": effective_parent_post_id,
|
||||
},
|
||||
}
|
||||
}
|
||||
if effective_parent_post_id:
|
||||
model_config_override["modelMap"]["imageEditModelConfig"][
|
||||
"parentPostId"
|
||||
] = effective_parent_post_id
|
||||
_log_final_image_edit_payload(
|
||||
prompt_text=prompt_text,
|
||||
file_attachments=file_attachments,
|
||||
|
||||
@@ -496,6 +496,51 @@ class VideoService:
|
||||
await upload_service.close()
|
||||
return uploaded
|
||||
|
||||
async def _prepare_reference_video_inputs(
|
||||
self,
|
||||
token: str,
|
||||
reference_items: list[dict[str, Any]],
|
||||
) -> tuple[str, list[dict[str, str]]]:
|
||||
primary_parent_post_id = ""
|
||||
prepared_items: list[dict[str, str]] = []
|
||||
upload_candidates: list[dict[str, Any]] = []
|
||||
|
||||
for index, item in enumerate(reference_items):
|
||||
normalized_item = dict(item or {})
|
||||
source_url = await self._resolve_reference_source_url(token, normalized_item)
|
||||
if not source_url:
|
||||
raise ValidationException(f"第 {index + 1} 张参考图缺少可用来源")
|
||||
|
||||
current_parent_post_id = str(
|
||||
normalized_item.get("parent_post_id") or ""
|
||||
).strip()
|
||||
mention_alias = str(normalized_item.get("mention_alias") or "").strip()
|
||||
|
||||
if current_parent_post_id and not primary_parent_post_id:
|
||||
primary_parent_post_id = current_parent_post_id
|
||||
prepared_items.append(
|
||||
{
|
||||
"file_id": current_parent_post_id,
|
||||
"asset_url": source_url,
|
||||
"source_url": source_url,
|
||||
"parent_post_id": current_parent_post_id,
|
||||
"mention_alias": mention_alias,
|
||||
"direct_parent": "1",
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
||||
normalized_item["source_image_url"] = source_url
|
||||
upload_candidates.append(normalized_item)
|
||||
|
||||
if upload_candidates:
|
||||
uploaded_items = await self._upload_reference_items(token, upload_candidates)
|
||||
for item in uploaded_items:
|
||||
item["direct_parent"] = "0"
|
||||
prepared_items.extend(uploaded_items)
|
||||
|
||||
return primary_parent_post_id, prepared_items
|
||||
|
||||
async def generate_from_reference_items(
|
||||
self,
|
||||
token: str,
|
||||
@@ -507,7 +552,9 @@ class VideoService:
|
||||
preset: str = "normal",
|
||||
) -> AsyncGenerator[bytes, None]:
|
||||
token_tag = _token_tag(token)
|
||||
uploaded_refs = await self._upload_reference_items(token, reference_items)
|
||||
primary_parent_post_id, uploaded_refs = await self._prepare_reference_video_inputs(
|
||||
token, reference_items
|
||||
)
|
||||
if not uploaded_refs:
|
||||
raise ValidationException("至少需要 1 张参考图")
|
||||
|
||||
@@ -539,13 +586,13 @@ class VideoService:
|
||||
file_attachments = [
|
||||
str(item.get("file_id") or "").strip()
|
||||
for item in uploaded_refs
|
||||
if str(item.get("file_id") or "").strip()
|
||||
if str(item.get("file_id") or "").strip() and str(item.get("direct_parent") or "") != "1"
|
||||
]
|
||||
message = f"{prompt_text} --mode=custom".strip()
|
||||
model_config_override = {
|
||||
"modelMap": {
|
||||
"videoGenModelConfig": {
|
||||
"parentPostId": post_id,
|
||||
"parentPostId": primary_parent_post_id or post_id,
|
||||
"aspectRatio": aspect_ratio,
|
||||
"videoLength": video_length,
|
||||
"resolutionName": resolution,
|
||||
|
||||
@@ -70,14 +70,28 @@
|
||||
return raw;
|
||||
}
|
||||
|
||||
function isImageLikeUrl(value) {
|
||||
const raw = normalizeUrl(value);
|
||||
if (!raw) return false;
|
||||
if (raw.startsWith('data:image/')) return true;
|
||||
if (/\/imagine-public\/images\/[0-9a-fA-F-]{32,36}(?:\.[a-z0-9]+|[/?#]|$)/i.test(raw)) return true;
|
||||
if (/\/imagine-public\/share-images\/[0-9a-fA-F-]{32,36}(?:\.[a-z0-9]+|[/?#]|$)/i.test(raw)) return true;
|
||||
if (/\/v1\/files\/image\//i.test(raw)) return true;
|
||||
if (/\/users\/.+\.(?:jpg|jpeg|png|webp|gif)(?:[?#].*)?$/i.test(raw)) return true;
|
||||
if (/\.(?:jpg|jpeg|png|webp|gif)(?:[?#].*)?$/i.test(raw)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function remember(entry) {
|
||||
if (!entry || typeof entry !== 'object') return null;
|
||||
|
||||
const parentPostId = extractParentPostId(entry.parentPostId || entry.parent_post_id || entry.id || '');
|
||||
if (!isParentPostId(parentPostId)) return null;
|
||||
|
||||
const sourceImageUrl = normalizeUrl(entry.sourceImageUrl || entry.source_image_url || '');
|
||||
const imageUrl = normalizeUrl(entry.imageUrl || entry.image_url || entry.url || '');
|
||||
const rawSourceImageUrl = normalizeUrl(entry.sourceImageUrl || entry.source_image_url || '');
|
||||
const rawImageUrl = normalizeUrl(entry.imageUrl || entry.image_url || entry.url || '');
|
||||
const sourceImageUrl = isImageLikeUrl(rawSourceImageUrl) ? rawSourceImageUrl : '';
|
||||
const imageUrl = isImageLikeUrl(rawImageUrl) ? rawImageUrl : '';
|
||||
const item = {
|
||||
parentPostId,
|
||||
sourceImageUrl: sourceImageUrl || imageUrl || buildImaginePublicUrl(parentPostId),
|
||||
@@ -114,8 +128,7 @@
|
||||
if (!parentPostId) return null;
|
||||
const hit = getByParentPostId(parentPostId);
|
||||
if (hit) return hit;
|
||||
const looksLikeUrl = raw.startsWith('http://') || raw.startsWith('https://') || raw.startsWith('/');
|
||||
const fallbackUrl = looksLikeUrl ? raw : buildImaginePublicUrl(parentPostId);
|
||||
const fallbackUrl = isImageLikeUrl(raw) ? raw : buildImaginePublicUrl(parentPostId);
|
||||
return {
|
||||
parentPostId,
|
||||
sourceImageUrl: fallbackUrl,
|
||||
|
||||
@@ -159,6 +159,17 @@
|
||||
return parentPostId ? buildImaginePublicUrl(parentPostId) : '';
|
||||
}
|
||||
|
||||
function isImagePreviewUrl(value) {
|
||||
const raw = String(value || '').trim();
|
||||
if (!raw) return false;
|
||||
if (raw.startsWith('data:image/')) return true;
|
||||
if (/\/imagine-public\/images\/[0-9a-fA-F-]{32,36}(?:\.jpg|\/|$)/i.test(raw)) return true;
|
||||
if (/\/v1\/files\/image\//i.test(raw)) return true;
|
||||
if (/\/users\/.+\.(?:jpg|jpeg|png|webp)(?:[?#].*)?$/i.test(raw)) return true;
|
||||
if (/\.(?:jpg|jpeg|png|webp)(?:[?#].*)?$/i.test(raw)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function pickPreviewUrl(hit, parentPostId) {
|
||||
const candidates = [
|
||||
hit && hit.imageUrl,
|
||||
@@ -169,7 +180,7 @@
|
||||
];
|
||||
for (const candidate of candidates) {
|
||||
const raw = String(candidate || '').trim();
|
||||
if (raw) return raw;
|
||||
if (isImagePreviewUrl(raw)) return raw;
|
||||
}
|
||||
const source = pickSourceImageUrl(hit, parentPostId);
|
||||
return source || (parentPostId ? buildImaginePublicUrl(parentPostId) : '');
|
||||
@@ -1438,15 +1449,23 @@
|
||||
if (references.length) {
|
||||
body.image_references = references;
|
||||
body.reference_items = referenceItems;
|
||||
const firstRef = references[0];
|
||||
if (firstRef.startsWith('data:image/')) {
|
||||
body.image_base64 = firstRef;
|
||||
} else {
|
||||
body.image_url = firstRef;
|
||||
const firstRefItem = referenceItems[0] || null;
|
||||
const firstRef = firstRefItem
|
||||
? String(firstRefItem.source_image_url || firstRefItem.image_url || '').trim()
|
||||
: '';
|
||||
if (firstRefItem && firstRefItem.parent_post_id) {
|
||||
body.parent_post_id = firstRefItem.parent_post_id;
|
||||
body.source_image_url = String(firstRefItem.source_image_url || firstRef || '').trim();
|
||||
} else if (firstRef) {
|
||||
if (firstRef.startsWith('data:image/')) {
|
||||
body.image_base64 = firstRef;
|
||||
} else {
|
||||
body.image_url = firstRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state.currentParentPostId) {
|
||||
if (state.currentParentPostId && (!body.reference_items || !body.reference_items.length)) {
|
||||
body.parent_post_id = state.currentParentPostId;
|
||||
if (state.currentSourceImageUrl) {
|
||||
body.source_image_url = state.currentSourceImageUrl;
|
||||
|
||||
@@ -712,6 +712,17 @@
|
||||
return `https://imagine-public.x.ai/imagine-public/images/${parentPostId}.jpg`;
|
||||
}
|
||||
|
||||
function isImagePreviewUrl(value) {
|
||||
const raw = String(value || '').trim();
|
||||
if (!raw) return false;
|
||||
if (raw.startsWith('data:image/')) return true;
|
||||
if (/\/imagine-public\/images\/[0-9a-fA-F-]{32,36}(?:\.[A-Za-z0-9]+|[/?#]|$)/i.test(raw)) return true;
|
||||
if (/\/v1\/files\/image\//i.test(raw)) return true;
|
||||
if (/\/users\/.+\.(?:jpg|jpeg|png|webp)(?:[?#].*)?$/i.test(raw)) return true;
|
||||
if (/\.(?:jpg|jpeg|png|webp)(?:[?#].*)?$/i.test(raw)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function pickPreviewUrl(hit, parentPostId, fallbackValue = '') {
|
||||
const candidates = [
|
||||
hit && hit.imageUrl,
|
||||
@@ -722,7 +733,7 @@
|
||||
];
|
||||
for (const candidate of candidates) {
|
||||
const raw = String(candidate || '').trim();
|
||||
if (raw) return raw;
|
||||
if (isImagePreviewUrl(raw)) return raw;
|
||||
}
|
||||
return pickSourceUrl(hit, parentPostId, fallbackValue);
|
||||
}
|
||||
@@ -923,6 +934,48 @@
|
||||
syncPromptRichInputFromTextarea();
|
||||
}
|
||||
|
||||
function appendReferenceItems(items, mode = 'upload') {
|
||||
const candidates = (Array.isArray(items) ? items : [])
|
||||
.filter((item) => item && (item.previewUrl || item.sourceUrl || item.url))
|
||||
.map((item) => ({
|
||||
...item,
|
||||
parentPostId: String(item.parentPostId || '').trim(),
|
||||
sourceUrl: String(item.sourceUrl || item.url || '').trim(),
|
||||
url: String(item.url || item.sourceUrl || '').trim()
|
||||
}));
|
||||
if (!candidates.length) return false;
|
||||
|
||||
const merged = Array.isArray(referenceImages) ? referenceImages.slice() : [];
|
||||
let appended = false;
|
||||
for (const item of candidates) {
|
||||
const itemParentId = String(item.parentPostId || '').trim();
|
||||
const itemSourceUrl = String(item.sourceUrl || item.url || '').trim();
|
||||
const exists = merged.some((current) => {
|
||||
const currentParentId = String(current.parentPostId || '').trim();
|
||||
const currentSourceUrl = String(current.sourceUrl || current.url || '').trim();
|
||||
if (itemParentId && currentParentId && itemParentId === currentParentId) return true;
|
||||
if (itemSourceUrl && currentSourceUrl && itemSourceUrl === currentSourceUrl) return true;
|
||||
return false;
|
||||
});
|
||||
if (exists) {
|
||||
continue;
|
||||
}
|
||||
if (merged.length >= REFERENCE_LIMIT) {
|
||||
toast(`最多支持 ${REFERENCE_LIMIT} 张参考图`, 'warning');
|
||||
break;
|
||||
}
|
||||
merged.push(item);
|
||||
appended = true;
|
||||
}
|
||||
|
||||
if (!appended) return false;
|
||||
setReferenceItems(
|
||||
merged,
|
||||
merged.some((item) => String(item.parentPostId || '').trim()) ? 'parent_post' : mode
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
function hideReferenceMentionMenu() {
|
||||
activeMentionIndex = -1;
|
||||
if (!referenceMentionMenu) return;
|
||||
@@ -1322,6 +1375,7 @@
|
||||
|
||||
function applyParentPostReference(text, options = {}) {
|
||||
const silent = Boolean(options.silent);
|
||||
const append = Boolean(options.append);
|
||||
const resolved = resolveReferenceByText(text);
|
||||
const raw = String(text || '').trim();
|
||||
const fallbackId = extractParentPostId(raw);
|
||||
@@ -1336,16 +1390,21 @@
|
||||
}
|
||||
return false;
|
||||
}
|
||||
setReferenceItems([{
|
||||
const targetItem = {
|
||||
id: makeReferenceId('parent'),
|
||||
previewUrl: finalPreviewUrl,
|
||||
sourceUrl: finalSourceUrl || finalPreviewUrl,
|
||||
url: finalPreviewUrl,
|
||||
parentPostId: finalParentId,
|
||||
name: finalParentId || 'parentPostId'
|
||||
}], 'parent_post');
|
||||
};
|
||||
if (append) {
|
||||
appendReferenceItems([targetItem], 'parent_post');
|
||||
} else {
|
||||
setReferenceItems([targetItem], 'parent_post');
|
||||
}
|
||||
if (!silent) {
|
||||
toast('已使用 parentPostId 填充参考图', 'success');
|
||||
toast(append ? '已追加参考图' : '已使用 parentPostId 填充参考图', 'success');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -3299,7 +3358,7 @@
|
||||
|
||||
if (applyParentBtn) {
|
||||
applyParentBtn.addEventListener('click', () => {
|
||||
applyParentPostReference(parentPostInput ? parentPostInput.value : '');
|
||||
applyParentPostReference(parentPostInput ? parentPostInput.value : '', { append: true });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3307,7 +3366,7 @@
|
||||
parentPostInput.addEventListener('keydown', (event) => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
applyParentPostReference(parentPostInput.value);
|
||||
applyParentPostReference(parentPostInput.value, { append: true });
|
||||
}
|
||||
});
|
||||
parentPostInput.addEventListener('input', () => {
|
||||
@@ -3326,7 +3385,7 @@
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
parentPostInput.value = text;
|
||||
applyParentPostReference(text, { silent: true });
|
||||
applyParentPostReference(text, { silent: true, append: true });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3368,13 +3427,13 @@
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
imageUrlInput.value = text;
|
||||
const applied = applyParentPostReference(text, { silent: true });
|
||||
const applied = applyParentPostReference(text, { silent: true, append: true });
|
||||
if (!applied) {
|
||||
const resolved = resolveReferenceByText(text);
|
||||
if (resolved.parentPostId && parentPostInput) {
|
||||
parentPostInput.value = resolved.parentPostId;
|
||||
}
|
||||
setReferenceItems([{
|
||||
appendReferenceItems([{
|
||||
id: makeReferenceId('url'),
|
||||
previewUrl: resolved.url || resolved.sourceUrl || text,
|
||||
sourceUrl: resolved.sourceUrl || text,
|
||||
@@ -3409,7 +3468,7 @@
|
||||
if (!isTypingInParentInput && !isTypingInImageUrlInput && (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target?.isContentEditable)) {
|
||||
return;
|
||||
}
|
||||
const applied = applyParentPostReference(text, { silent: true });
|
||||
const applied = applyParentPostReference(text, { silent: true, append: true });
|
||||
if (applied) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
<div id="app-footer"></div>
|
||||
|
||||
<script src="/static/common/js/admin-auth.js?v=0.3.0"></script>
|
||||
<script src="/static/common/js/parentpost-memory.js?v=0.1.0"></script>
|
||||
<script src="/static/common/js/parentpost-memory.js?v=0.1.1"></script>
|
||||
<script src="/static/common/js/public-header.js?v=0.3.3"></script>
|
||||
<script src="/static/common/js/footer.js?v=0.3.0"></script>
|
||||
<script src="/static/common/js/toast.js"></script>
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
<div id="mobileSettingsOverlay" class="mobile-settings-overlay"></div>
|
||||
|
||||
<script src="/static/common/js/admin-auth.js?v=0.3.0"></script>
|
||||
<script src="/static/common/js/parentpost-memory.js?v=0.1.0"></script>
|
||||
<script src="/static/common/js/parentpost-memory.js?v=0.1.1"></script>
|
||||
<script src="/static/common/js/public-header.js?v=0.3.3"></script>
|
||||
<script src="/static/common/js/footer.js?v=0.3.0"></script>
|
||||
<script src="/static/common/js/toast.js"></script>
|
||||
|
||||
Reference in new issue
Block a user