Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 86e0f83f73 | |||
| 2bc6fb7ab1 | |||
| 65be92ba43 | |||
| 98acb79a20 | |||
| d819cecfc6 |
@@ -32,7 +32,6 @@ import {
|
|||||||
Gift,
|
Gift,
|
||||||
MagicWand,
|
MagicWand,
|
||||||
Mountains,
|
Mountains,
|
||||||
PaperPlaneRight,
|
|
||||||
ShoppingBag,
|
ShoppingBag,
|
||||||
User,
|
User,
|
||||||
VideoCamera,
|
VideoCamera,
|
||||||
@@ -52,6 +51,7 @@ import EcommerceSetPanel from "./panels/EcommerceSetPanel";
|
|||||||
import EcommerceTryOnPanel from "./panels/EcommerceTryOnPanel";
|
import EcommerceTryOnPanel from "./panels/EcommerceTryOnPanel";
|
||||||
import EcommerceClonePanel from "./panels/EcommerceClonePanel";
|
import EcommerceClonePanel from "./panels/EcommerceClonePanel";
|
||||||
import EcommerceCopywritingPanel from "./panels/EcommerceCopywritingPanel";
|
import EcommerceCopywritingPanel from "./panels/EcommerceCopywritingPanel";
|
||||||
|
import EcommerceOneClickVideoPanel from "./panels/EcommerceOneClickVideoPanel";
|
||||||
import { ecommerceOssScopes, saveUnifiedEcommerceGenerationRecord, deleteEcommerceGenerationRecord } from "./ecommerceGenerationPersistence";
|
import { ecommerceOssScopes, saveUnifiedEcommerceGenerationRecord, deleteEcommerceGenerationRecord } from "./ecommerceGenerationPersistence";
|
||||||
import { downloadResultAsset } from "../workbench/workbenchDownload";
|
import { downloadResultAsset } from "../workbench/workbenchDownload";
|
||||||
import type { CloneOutputKey, ProductSetOutputKey } from "./utils/platformRules";
|
import type { CloneOutputKey, ProductSetOutputKey } from "./utils/platformRules";
|
||||||
@@ -290,9 +290,7 @@ type CloneModelPanelTab = "scene" | "model";
|
|||||||
type CloneVideoQualityKey = "standard" | "high" | "ultra";
|
type CloneVideoQualityKey = "standard" | "high" | "ultra";
|
||||||
type ProductSetStatus = "idle" | "ready" | "generating" | "done" | "failed";
|
type ProductSetStatus = "idle" | "ready" | "generating" | "done" | "failed";
|
||||||
type ProductKitToolKey = "set" | "detail" | "wear" | "clone";
|
type ProductKitToolKey = "set" | "detail" | "wear" | "clone";
|
||||||
type ComposerMenuKey = "mode" | "platform" | "language" | "ratio" | "settings" | "assetLibrary" | "workMode" | "aiWrite";
|
type ComposerMenuKey = "mode" | "platform" | "language" | "ratio" | "settings";
|
||||||
type ComposerAssetTabKey = "recent" | "recipe" | "model";
|
|
||||||
type ComposerWorkModeKey = "quick" | "think";
|
|
||||||
type CloneBasicSelectKey = "platform" | "market" | "language" | "ratio";
|
type CloneBasicSelectKey = "platform" | "market" | "language" | "ratio";
|
||||||
type CloneModelSelectKey = "gender" | "age" | "ethnicity" | "body";
|
type CloneModelSelectKey = "gender" | "age" | "ethnicity" | "body";
|
||||||
type CloneReferenceMode = "upload" | "link";
|
type CloneReferenceMode = "upload" | "link";
|
||||||
@@ -1065,13 +1063,11 @@ const commerceScenarioOptions: Array<{ key: CommerceScenarioKey; label: string;
|
|||||||
{ key: "model", label: "模特图", desc: "真人展示", icon: <span role="img" aria-label="model">🕴️</span> },
|
{ key: "model", label: "模特图", desc: "真人展示", icon: <span role="img" aria-label="model">🕴️</span> },
|
||||||
{ key: "scene", label: "场景图", desc: "生活氛围", icon: <span role="img" aria-label="scene">🌅</span> },
|
{ key: "scene", label: "场景图", desc: "生活氛围", icon: <span role="img" aria-label="scene">🌅</span> },
|
||||||
{ key: "festival", label: "节日风格图", desc: "节点营销", icon: <span role="img" aria-label="festival">🎉</span> },
|
{ key: "festival", label: "节日风格图", desc: "节点营销", icon: <span role="img" aria-label="festival">🎉</span> },
|
||||||
{ key: "salesVideo", label: "带货视频", desc: "短视频脚本", icon: <span role="img" aria-label="video">🎬</span> },
|
|
||||||
{ key: "background", label: "更换背景", desc: "背景重构", icon: <span role="img" aria-label="background">✨</span> },
|
{ key: "background", label: "更换背景", desc: "背景重构", icon: <span role="img" aria-label="background">✨</span> },
|
||||||
{ key: "retouch", label: "无痕改图", desc: "精修优化", icon: <span role="img" aria-label="retouch">🪄</span> },
|
{ key: "retouch", label: "无痕改图", desc: "精修优化", icon: <span role="img" aria-label="retouch">🪄</span> },
|
||||||
|
{ key: "salesVideo", label: "带货视频", desc: "短视频脚本", icon: <span role="img" aria-label="video">🎬</span> },
|
||||||
];
|
];
|
||||||
const primaryCommerceScenarioKeys: CommerceScenarioKey[] = ["popular", "poster", "mainImage", "model"];
|
const primaryCommerceScenarioKeys: CommerceScenarioKey[] = ["popular", "poster", "mainImage", "model"];
|
||||||
const scenarioSettingsKeys: CommerceScenarioKey[] = ["poster", "mainImage", "model", "scene", "festival", "salesVideo"];
|
|
||||||
const scenarioAdvancedSettingsKeys: CommerceScenarioKey[] = ["model", "salesVideo"];
|
|
||||||
const commerceScenarioOutputMap: Record<Exclude<CommerceScenarioKey, "popular">, ProductSetOutputKey> = {
|
const commerceScenarioOutputMap: Record<Exclude<CommerceScenarioKey, "popular">, ProductSetOutputKey> = {
|
||||||
poster: "set",
|
poster: "set",
|
||||||
mainImage: "set",
|
mainImage: "set",
|
||||||
@@ -1429,7 +1425,6 @@ const maxCloneProductImages = 20;
|
|||||||
const maxCloneReferenceImages = 20;
|
const maxCloneReferenceImages = 20;
|
||||||
const cloneVideoDurationMin = 5;
|
const cloneVideoDurationMin = 5;
|
||||||
const cloneVideoDurationMax = 45;
|
const cloneVideoDurationMax = 45;
|
||||||
const composerDurationOptions = [5, 10, 15];
|
|
||||||
const defaultEcommercePlatform = "淘宝/天猫";
|
const defaultEcommercePlatform = "淘宝/天猫";
|
||||||
const defaultProductSetOutput: ProductSetOutputKey = "set";
|
const defaultProductSetOutput: ProductSetOutputKey = "set";
|
||||||
const defaultCloneOutput: CloneOutputKey = "set";
|
const defaultCloneOutput: CloneOutputKey = "set";
|
||||||
@@ -1559,42 +1554,6 @@ const blobToDataUrl = (blob: Blob): Promise<string> =>
|
|||||||
reader.readAsDataURL(blob);
|
reader.readAsDataURL(blob);
|
||||||
});
|
});
|
||||||
|
|
||||||
function createLocalImageItems(files: File[], limit: number, prefix: string): CloneImageItem[] {
|
|
||||||
const selectedFiles = Array.from(files).slice(0, limit);
|
|
||||||
const stamp = Date.now();
|
|
||||||
return selectedFiles.map((file, index) => {
|
|
||||||
const localPreviewUrl = URL.createObjectURL(file);
|
|
||||||
const mimeType = normalizeEcommerceImageMime(file.type);
|
|
||||||
return {
|
|
||||||
id: `${prefix}-${stamp}-${index}`,
|
|
||||||
src: localPreviewUrl,
|
|
||||||
name: file.name,
|
|
||||||
file,
|
|
||||||
format: getImageFileFormat(file),
|
|
||||||
mimeType,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function uploadImageItem(item: CloneImageItem): Promise<{ src?: string; ossKey?: string; width?: number; height?: number }> {
|
|
||||||
if (!item.file) return {};
|
|
||||||
const mimeType = normalizeEcommerceImageMime(item.file.type);
|
|
||||||
try {
|
|
||||||
const uploadBlob = item.file.type === mimeType ? item.file : new Blob([item.file], { type: mimeType });
|
|
||||||
const [uploaded, dimensions] = await Promise.all([
|
|
||||||
aiGenerationClient.uploadAssetBinary(uploadBlob, {
|
|
||||||
name: item.file.name,
|
|
||||||
mimeType,
|
|
||||||
scope: ecommerceOssScopes.productSource,
|
|
||||||
}),
|
|
||||||
readImageDimensions(item.src).catch(() => ({})),
|
|
||||||
]);
|
|
||||||
return { src: uploaded.url, ossKey: uploaded.ossKey, ...dimensions };
|
|
||||||
} catch {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createUploadedImageItems(files: File[], limit: number, prefix: string): Promise<CloneImageItem[]> {
|
async function createUploadedImageItems(files: File[], limit: number, prefix: string): Promise<CloneImageItem[]> {
|
||||||
const selectedFiles = Array.from(files).slice(0, limit);
|
const selectedFiles = Array.from(files).slice(0, limit);
|
||||||
const stamp = Date.now();
|
const stamp = Date.now();
|
||||||
@@ -1927,7 +1886,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
const [selectedProductSetPreview, setSelectedProductSetPreview] = useState<ProductSetPreviewSelection | null>(null);
|
const [selectedProductSetPreview, setSelectedProductSetPreview] = useState<ProductSetPreviewSelection | null>(null);
|
||||||
const [showHostingModal, setShowHostingModal] = useState(false);
|
const [showHostingModal, setShowHostingModal] = useState(false);
|
||||||
const [productImages, setProductImages] = useState<CloneImageItem[]>([]);
|
const [productImages, setProductImages] = useState<CloneImageItem[]>([]);
|
||||||
const [activeQuickTool, setActiveQuickTool] = useState<"cutout" | "detail" | "watermark" | "image-edit" | "translate" | "hot" | "quick-set" | "copywriting" | null>(null);
|
const [activeQuickTool, setActiveQuickTool] = useState<"cutout" | "detail" | "watermark" | "image-edit" | "translate" | "hot" | "quick-set" | "copywriting" | "oneClickVideo" | null>(null);
|
||||||
const [smartCutoutImage, setSmartCutoutImage] = useState<SmartCutoutImageItem | null>(null);
|
const [smartCutoutImage, setSmartCutoutImage] = useState<SmartCutoutImageItem | null>(null);
|
||||||
const [smartCutoutBatchImages, setSmartCutoutBatchImages] = useState<SmartCutoutImageItem[]>([]);
|
const [smartCutoutBatchImages, setSmartCutoutBatchImages] = useState<SmartCutoutImageItem[]>([]);
|
||||||
const [smartCutoutBackgroundColor, setSmartCutoutBackgroundColor] = useState("#ffffff");
|
const [smartCutoutBackgroundColor, setSmartCutoutBackgroundColor] = useState("#ffffff");
|
||||||
@@ -1979,10 +1938,6 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
const [isComposerMenuClosing, setIsComposerMenuClosing] = useState(false);
|
const [isComposerMenuClosing, setIsComposerMenuClosing] = useState(false);
|
||||||
const [composerPopoverLeft, setComposerPopoverLeft] = useState(0);
|
const [composerPopoverLeft, setComposerPopoverLeft] = useState(0);
|
||||||
const [composerPopoverTop, setComposerPopoverTop] = useState(0);
|
const [composerPopoverTop, setComposerPopoverTop] = useState(0);
|
||||||
const [composerTooltip, setComposerTooltip] = useState<{ text: string; left: number; top: number } | null>(null);
|
|
||||||
const [composerAssetTab, setComposerAssetTab] = useState<ComposerAssetTabKey>("recent");
|
|
||||||
const [composerWorkMode, setComposerWorkMode] = useState<ComposerWorkModeKey>("quick");
|
|
||||||
const [aiWriteDraft, setAiWriteDraft] = useState("");
|
|
||||||
const [isCommandHistoryCollapsed, setIsCommandHistoryCollapsed] = useState(true);
|
const [isCommandHistoryCollapsed, setIsCommandHistoryCollapsed] = useState(true);
|
||||||
const [inspirationPreview, setInspirationPreview] = useState<{ mediaUrl: string; mediaType: "image" | "video"; prompt: string } | null>(null);
|
const [inspirationPreview, setInspirationPreview] = useState<{ mediaUrl: string; mediaType: "image" | "video"; prompt: string } | null>(null);
|
||||||
const [isQuickPanelCollapsed, setIsQuickPanelCollapsed] = useState(false);
|
const [isQuickPanelCollapsed, setIsQuickPanelCollapsed] = useState(false);
|
||||||
@@ -2446,18 +2401,6 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
[cloneOutput, platform],
|
[cloneOutput, platform],
|
||||||
);
|
);
|
||||||
const cloneRatioOptions = baseCloneRatioOptions;
|
const cloneRatioOptions = baseCloneRatioOptions;
|
||||||
const composerRatioOptions = useMemo(
|
|
||||||
() => [
|
|
||||||
"1000×1000px\u00a0\u00a0\u00a01:1",
|
|
||||||
"800×1200px\u00a0\u00a0\u00a02:3",
|
|
||||||
"1200×800px\u00a0\u00a0\u00a03:2",
|
|
||||||
"1200×900px\u00a0\u00a0\u00a04:3",
|
|
||||||
"900×1200px\u00a0\u00a0\u00a03:4",
|
|
||||||
"1080×1920px\u00a0\u00a0\u00a09:16",
|
|
||||||
"1920×1080px\u00a0\u00a0\u00a016:9",
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
const productSetLanguageOptions = useMemo(
|
const productSetLanguageOptions = useMemo(
|
||||||
() => getPlatformLanguageOptions(productSetPlatform, productSetMarket),
|
() => getPlatformLanguageOptions(productSetPlatform, productSetMarket),
|
||||||
[productSetMarket, productSetPlatform],
|
[productSetMarket, productSetPlatform],
|
||||||
@@ -2503,7 +2446,6 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
: activeCommerceScenario === "popular"
|
: activeCommerceScenario === "popular"
|
||||||
? popularCommerceScenarioTemplates
|
? popularCommerceScenarioTemplates
|
||||||
: commerceScenarioTemplates.filter((template) => template.scenario === activeCommerceScenario);
|
: commerceScenarioTemplates.filter((template) => template.scenario === activeCommerceScenario);
|
||||||
const shouldShowScenarioSettings = activeCommerceScenario !== null && scenarioSettingsKeys.includes(activeCommerceScenario);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
templateStripRef.current?.scrollTo({ left: 0, behavior: "auto" });
|
templateStripRef.current?.scrollTo({ left: 0, behavior: "auto" });
|
||||||
}, [activeCommerceScenario, isCloneTemplateStripVisible]);
|
}, [activeCommerceScenario, isCloneTemplateStripVisible]);
|
||||||
@@ -2589,30 +2531,20 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const addSetImages = (files: File[]) => {
|
const addSetImages = async (files: File[]) => {
|
||||||
if (setImages.length >= 3) return;
|
if (setImages.length >= 3) return;
|
||||||
const imageFiles = notifyRejectedImages(files);
|
const imageFiles = notifyRejectedImages(files);
|
||||||
if (!imageFiles.length) return;
|
if (!imageFiles.length) return;
|
||||||
const remainingSlots = 3 - setImages.length;
|
try {
|
||||||
if (remainingSlots <= 0) return;
|
const nextImages = await createUploadedImageItems(imageFiles, 3 - setImages.length, "set");
|
||||||
|
setSetImages((current) => {
|
||||||
const localItems = createLocalImageItems(imageFiles, remainingSlots, "set");
|
if (current.length >= 3) return current;
|
||||||
setSetImages((current) => [...current, ...localItems].slice(0, 3));
|
return nextImages.length ? [...current, ...nextImages].slice(0, 3) : current;
|
||||||
setProductSetStatus("ready");
|
});
|
||||||
|
setProductSetStatus("ready");
|
||||||
Promise.all(localItems.map(async (item) => {
|
} catch (err) {
|
||||||
const uploaded = await uploadImageItem(item);
|
toast.error(err instanceof Error ? err.message : "商品图上传失败");
|
||||||
if (uploaded.src) URL.revokeObjectURL(item.src);
|
}
|
||||||
return { id: item.id, uploaded };
|
|
||||||
})).then((results) => {
|
|
||||||
const updateMap = new Map(results.map((result) => [result.id, result.uploaded]));
|
|
||||||
setSetImages((current) => current.map((item) => {
|
|
||||||
const update = updateMap.get(item.id);
|
|
||||||
return update ? { ...item, ...update } : item;
|
|
||||||
}));
|
|
||||||
}).catch(() => {
|
|
||||||
toast.error("套图后台上传失败,请检查网络后重试");
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSetUpload = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleSetUpload = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
@@ -3697,33 +3629,20 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const addProductImages = (files: File[]) => {
|
const addProductImages = async (files: File[]) => {
|
||||||
const imageFiles = notifyRejectedImages(files);
|
const imageFiles = notifyRejectedImages(files);
|
||||||
if (!imageFiles.length) return;
|
if (!imageFiles.length) return;
|
||||||
const remainingSlots = maxCloneProductImages - productImages.length;
|
try {
|
||||||
if (remainingSlots <= 0) return;
|
const nextImages = await createUploadedImageItems(imageFiles, maxCloneProductImages - productImages.length, "product");
|
||||||
|
setProductImages((current) => {
|
||||||
const localItems = createLocalImageItems(imageFiles, remainingSlots, "product");
|
if (current.length >= maxCloneProductImages) return current;
|
||||||
setProductImages((current) => [...current, ...localItems].slice(0, maxCloneProductImages));
|
return nextImages.length ? [...current, ...nextImages].slice(0, maxCloneProductImages) : current;
|
||||||
setStatus("ready");
|
});
|
||||||
setResults([]);
|
setStatus("ready");
|
||||||
|
setResults([]);
|
||||||
Promise.all(localItems.map(async (item) => {
|
} catch (err) {
|
||||||
const uploaded = await uploadImageItem(item);
|
toast.error(err instanceof Error ? err.message : "商品图上传失败");
|
||||||
if (uploaded.src) {
|
}
|
||||||
URL.revokeObjectURL(item.src);
|
|
||||||
}
|
|
||||||
return { id: item.id, uploaded };
|
|
||||||
})).then((results) => {
|
|
||||||
const updateMap = new Map(results.map((result) => [result.id, result.uploaded]));
|
|
||||||
setProductImages((current) => current.map((item) => {
|
|
||||||
const update = updateMap.get(item.id);
|
|
||||||
if (!update) return item;
|
|
||||||
return { ...item, ...update };
|
|
||||||
}));
|
|
||||||
}).catch(() => {
|
|
||||||
toast.error("商品图后台上传失败,请检查网络后重试");
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleProductUpload = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleProductUpload = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
@@ -3777,29 +3696,22 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const addCloneReferenceImages = (files: File[]) => {
|
const addCloneReferenceImages = async (files: File[]) => {
|
||||||
const imageFiles = notifyRejectedImages(files);
|
const imageFiles = notifyRejectedImages(files);
|
||||||
if (!imageFiles.length) return;
|
if (!imageFiles.length) return;
|
||||||
const remainingSlots = maxCloneReferenceImages - cloneReferenceImages.length;
|
const remainingSlots = maxCloneReferenceImages - cloneReferenceImages.length;
|
||||||
if (remainingSlots <= 0) return;
|
if (remainingSlots <= 0) return;
|
||||||
|
try {
|
||||||
const localItems = createLocalImageItems(imageFiles, remainingSlots, "reference");
|
const nextImages = await createUploadedImageItems(imageFiles, remainingSlots, "reference");
|
||||||
setCloneReferenceImages((current) => [...current, ...localItems].slice(0, maxCloneReferenceImages));
|
if (!nextImages.length) return;
|
||||||
hydrateCloneReferenceImageMeta(localItems);
|
setCloneReferenceImages((current) => {
|
||||||
|
if (current.length >= maxCloneReferenceImages) return current;
|
||||||
Promise.all(localItems.map(async (item) => {
|
return nextImages.length ? [...current, ...nextImages].slice(0, maxCloneReferenceImages) : current;
|
||||||
const uploaded = await uploadImageItem(item);
|
});
|
||||||
if (uploaded.src) URL.revokeObjectURL(item.src);
|
hydrateCloneReferenceImageMeta(nextImages);
|
||||||
return { id: item.id, uploaded };
|
} catch (err) {
|
||||||
})).then((results) => {
|
toast.error(err instanceof Error ? err.message : "参考图上传失败");
|
||||||
const updateMap = new Map(results.map((result) => [result.id, result.uploaded]));
|
}
|
||||||
setCloneReferenceImages((current) => current.map((item) => {
|
|
||||||
const update = updateMap.get(item.id);
|
|
||||||
return update ? { ...item, ...update } : item;
|
|
||||||
}));
|
|
||||||
}).catch(() => {
|
|
||||||
toast.error("参考图后台上传失败,请检查网络后重试");
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeCloneReferenceImage = (imageId: string) => {
|
const removeCloneReferenceImage = (imageId: string) => {
|
||||||
@@ -3933,8 +3845,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
|
|
||||||
const handleCommerceScenarioClick = (nextScenario: CommerceScenarioKey) => {
|
const handleCommerceScenarioClick = (nextScenario: CommerceScenarioKey) => {
|
||||||
if (nextScenario === activeCommerceScenario) {
|
if (nextScenario === activeCommerceScenario) {
|
||||||
setActiveCommerceScenario(null);
|
setIsCloneTemplateStripVisible((visible) => !visible);
|
||||||
setIsCloneTemplateStripVisible(false);
|
|
||||||
setComposerMenu(null);
|
setComposerMenu(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4255,38 +4166,23 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
};
|
};
|
||||||
}, [openCloneModelSelect]);
|
}, [openCloneModelSelect]);
|
||||||
|
|
||||||
const addGarmentImages = (files: File[]) => {
|
|
||||||
const uploadedFiles = notifyRejectedImages(files);
|
|
||||||
if (!uploadedFiles.length) return;
|
|
||||||
const remainingSlots = 5 - garmentImages.length;
|
|
||||||
if (remainingSlots <= 0) return;
|
|
||||||
|
|
||||||
const localItems = createLocalImageItems(uploadedFiles, remainingSlots, "garment");
|
|
||||||
setGarmentImages((current) => [...current, ...localItems].slice(0, 5));
|
|
||||||
setTryOnStatus("ready");
|
|
||||||
|
|
||||||
Promise.all(localItems.map(async (item) => {
|
|
||||||
const uploaded = await uploadImageItem(item);
|
|
||||||
if (uploaded.src) URL.revokeObjectURL(item.src);
|
|
||||||
return { id: item.id, uploaded };
|
|
||||||
})).then((results) => {
|
|
||||||
const updateMap = new Map(results.map((result) => [result.id, result.uploaded]));
|
|
||||||
setGarmentImages((current) => current.map((item) => {
|
|
||||||
const update = updateMap.get(item.id);
|
|
||||||
return update ? { ...item, ...update } : item;
|
|
||||||
}));
|
|
||||||
}).catch(() => {
|
|
||||||
toast.error("服饰图后台上传失败,请检查网络后重试");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleGarmentUpload = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleGarmentUpload = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
const files = event.target.files;
|
const files = event.target.files;
|
||||||
if (!files?.length) {
|
if (!files?.length) return;
|
||||||
|
const uploadedFiles = notifyRejectedImages(Array.from(files));
|
||||||
|
if (!uploadedFiles.length) {
|
||||||
event.target.value = "";
|
event.target.value = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addGarmentImages(Array.from(files));
|
void (async () => {
|
||||||
|
try {
|
||||||
|
const nextImages = await createUploadedImageItems(uploadedFiles, 5 - garmentImages.length, "garment");
|
||||||
|
setGarmentImages((current) => [...current, ...nextImages].slice(0, 5));
|
||||||
|
setTryOnStatus("ready");
|
||||||
|
} catch (err) {
|
||||||
|
toast.error(err instanceof Error ? err.message : "服饰图上传失败");
|
||||||
|
}
|
||||||
|
})();
|
||||||
event.target.value = "";
|
event.target.value = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4322,30 +4218,20 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
reader.readAsDataURL(blob);
|
reader.readAsDataURL(blob);
|
||||||
});
|
});
|
||||||
|
|
||||||
const addDetailImages = (files: File[]) => {
|
const addDetailImages = async (files: File[]) => {
|
||||||
const uploadedFiles = notifyRejectedImages(files);
|
const uploadedFiles = notifyRejectedImages(files);
|
||||||
if (!uploadedFiles.length) return;
|
if (!uploadedFiles.length) return;
|
||||||
const remainingSlots = 3 - detailProductImages.length;
|
try {
|
||||||
if (remainingSlots <= 0) return;
|
const nextImages = await createUploadedImageItems(uploadedFiles, 3 - detailProductImages.length, "detail");
|
||||||
|
setDetailProductImages((current) => {
|
||||||
const localItems = createLocalImageItems(uploadedFiles, remainingSlots, "detail");
|
if (current.length >= 3) return current;
|
||||||
setDetailProductImages((current) => [...current, ...localItems].slice(0, 3));
|
return nextImages.length ? [...current, ...nextImages].slice(0, 3) : current;
|
||||||
setDetailStatus("ready");
|
});
|
||||||
setDetailResultUrl(null);
|
setDetailStatus("ready");
|
||||||
|
setDetailResultUrl(null);
|
||||||
Promise.all(localItems.map(async (item) => {
|
} catch (err) {
|
||||||
const uploaded = await uploadImageItem(item);
|
toast.error(err instanceof Error ? err.message : "详情图上传失败");
|
||||||
if (uploaded.src) URL.revokeObjectURL(item.src);
|
}
|
||||||
return { id: item.id, uploaded };
|
|
||||||
})).then((results) => {
|
|
||||||
const updateMap = new Map(results.map((result) => [result.id, result.uploaded]));
|
|
||||||
setDetailProductImages((current) => current.map((item) => {
|
|
||||||
const update = updateMap.get(item.id);
|
|
||||||
return update ? { ...item, ...update } : item;
|
|
||||||
}));
|
|
||||||
}).catch(() => {
|
|
||||||
toast.error("详情图后台上传失败,请检查网络后重试");
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadCloneImages = async (images: CloneImageItem[]): Promise<string[]> => {
|
const uploadCloneImages = async (images: CloneImageItem[]): Promise<string[]> => {
|
||||||
@@ -5134,6 +5020,26 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
setComposerMenu(null);
|
setComposerMenu(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openOneClickVideoPage = () => {
|
||||||
|
clearSmartCutoutTransition();
|
||||||
|
setActiveQuickTool("oneClickVideo");
|
||||||
|
setComposerMenu(null);
|
||||||
|
setIsCloneSettingsCollapsed(false);
|
||||||
|
setIsQuickPanelCollapsed(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeOneClickVideoPage = () => {
|
||||||
|
setActiveQuickTool(null);
|
||||||
|
setComposerMenu(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOneClickVideoPlatformChange = (nextPlatform: string) => {
|
||||||
|
const normalizedPlatform = normalizePlatform(nextPlatform);
|
||||||
|
setPlatform(normalizedPlatform);
|
||||||
|
setRatio((current) => normalizeRatioForPlatform(normalizedPlatform, current, "video"));
|
||||||
|
setLanguage(getPlatformDefaultLanguage(normalizedPlatform, market));
|
||||||
|
};
|
||||||
|
|
||||||
const resetTask = () => {
|
const resetTask = () => {
|
||||||
setSetImages([]);
|
setSetImages([]);
|
||||||
setProductSetRequirement("");
|
setProductSetRequirement("");
|
||||||
@@ -5199,6 +5105,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
const isHotCloneTool = isCloneTool && activeQuickTool === "hot";
|
const isHotCloneTool = isCloneTool && activeQuickTool === "hot";
|
||||||
const isQuickSetTool = isCloneTool && activeQuickTool === "quick-set";
|
const isQuickSetTool = isCloneTool && activeQuickTool === "quick-set";
|
||||||
const isCopywritingTool = isCloneTool && activeQuickTool === "copywriting";
|
const isCopywritingTool = isCloneTool && activeQuickTool === "copywriting";
|
||||||
|
const isOneClickVideoTool = isCloneTool && activeQuickTool === "oneClickVideo";
|
||||||
const pageLabel = isSetTool ? "商品套图" : isDetail ? "A+/详情页" : isTryOn ? "AI服饰穿戴" : activeToolMeta?.label || "商品工具";
|
const pageLabel = isSetTool ? "商品套图" : isDetail ? "A+/详情页" : isTryOn ? "AI服饰穿戴" : activeToolMeta?.label || "商品工具";
|
||||||
const setPrimaryLabel =
|
const setPrimaryLabel =
|
||||||
setImages.length === 0
|
setImages.length === 0
|
||||||
@@ -5918,96 +5825,6 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
? String(cloneVideoDuration) + "秒 " + (cloneVideoQuality === "standard" ? "720P" : "1080P")
|
? String(cloneVideoDuration) + "秒 " + (cloneVideoQuality === "standard" ? "720P" : "1080P")
|
||||||
: "换装素材";
|
: "换装素材";
|
||||||
|
|
||||||
const composerAssetTabs: Array<{ key: ComposerAssetTabKey; label: string }> = [
|
|
||||||
{ key: "recent", label: "最近保存" },
|
|
||||||
{ key: "recipe", label: "套图配方" },
|
|
||||||
{ key: "model", label: "模特库" },
|
|
||||||
];
|
|
||||||
const composerWorkModeOptions: Array<{ key: ComposerWorkModeKey; label: string; desc: string }> = [
|
|
||||||
{ key: "quick", label: "快捷", desc: "快速整理提示词,适合常规商品图生成。" },
|
|
||||||
{ key: "think", label: "思考", desc: "更强调卖点拆解、场景规划和图文一致性。" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const applyAiWriteSuggestion = () => {
|
|
||||||
const keyword = aiWriteDraft.trim();
|
|
||||||
if (!keyword) {
|
|
||||||
toast.info("请输入产品关键词或卖点");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const modeHint = composerWorkMode === "think" ? "先拆解目标人群、核心卖点和使用场景," : "";
|
|
||||||
const nextValue = `${keyword}。${modeHint}请生成适合${platform}的高转化电商素材,画面干净高级,突出产品主体、核心卖点、使用场景和购买理由。`.slice(0, 500);
|
|
||||||
setRequirement(nextValue);
|
|
||||||
setComposerMenu(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderComposerAssetPanel = () => {
|
|
||||||
const renderEmpty = (label: string) => (
|
|
||||||
<div className="ecom-command-library-empty">
|
|
||||||
<FolderOpenOutlined />
|
|
||||||
<strong>暂无数据</strong>
|
|
||||||
<span>{label}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
let content: ReactNode;
|
|
||||||
if (composerAssetTab === "recent") {
|
|
||||||
content = ecommerceHistoryRecords.length ? (
|
|
||||||
<div className="ecom-command-library-list">
|
|
||||||
{ecommerceHistoryRecords.slice(0, 4).map((record) => {
|
|
||||||
const outputLabel = cloneOutputOptions.find((option) => option.key === record.output)?.label || "生成记录";
|
|
||||||
return (
|
|
||||||
<button key={record.id} type="button" onClick={() => { openEcommerceHistoryRecord(record); setComposerMenu(null); }}>
|
|
||||||
<strong>{record.title}</strong>
|
|
||||||
<span>{outputLabel} · {formatHistoryTime(record.createdAt)}</span>
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
) : renderEmpty("生成后保存的素材会沉淀在这里");
|
|
||||||
} else if (composerAssetTab === "recipe") {
|
|
||||||
content = (
|
|
||||||
<div className="ecom-command-library-list">
|
|
||||||
{commerceScenarioTemplates.slice(0, 4).map((template) => (
|
|
||||||
<button key={template.id} type="button" onClick={() => { handleCloneTemplateCardClick(template); setComposerMenu(null); }}>
|
|
||||||
<strong>{template.title}</strong>
|
|
||||||
<span>{template.badge} · {template.desc}</span>
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
content = (
|
|
||||||
<div className="ecom-command-library-list ecom-command-library-list--model">
|
|
||||||
{tryOnScenes.slice(0, 4).map((scene) => (
|
|
||||||
<button key={scene} type="button" className={selectedCloneModelScenes.includes(scene) ? "is-active" : ""} onClick={() => toggleCloneModelScene(scene)}>
|
|
||||||
<strong>{scene}</strong>
|
|
||||||
<span>模特场景</span>
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<header className="ecom-command-library-head">
|
|
||||||
<strong>资产库</strong>
|
|
||||||
<button type="button" className="ecom-command-library-help" onClick={(event) => event.preventDefault()}>
|
|
||||||
<QuestionCircleOutlined /> 使用教程
|
|
||||||
</button>
|
|
||||||
</header>
|
|
||||||
<div className="ecom-command-library-tabs" role="tablist" aria-label="资产库分类">
|
|
||||||
{composerAssetTabs.map((tab) => (
|
|
||||||
<button key={tab.key} type="button" className={composerAssetTab === tab.key ? "is-active" : ""} onClick={() => setComposerAssetTab(tab.key)}>
|
|
||||||
{tab.label}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{content}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderComposerMenu = () => {
|
const renderComposerMenu = () => {
|
||||||
const composerLanguageOptions = Array.from(new Set(marketLanguageOptions.flatMap((option) => option.languages))).map((item) => ({
|
const composerLanguageOptions = Array.from(new Set(marketLanguageOptions.flatMap((option) => option.languages))).map((item) => ({
|
||||||
language: item,
|
language: item,
|
||||||
@@ -6021,37 +5838,6 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
if (!menuToRender) return null;
|
if (!menuToRender) return null;
|
||||||
const popoverClosingClass = !composerMenu && isComposerMenuClosing ? " is-closing" : "";
|
const popoverClosingClass = !composerMenu && isComposerMenuClosing ? " is-closing" : "";
|
||||||
const composerPopoverKey = `${menuToRender}-${cloneOutput}-${popoverClosingClass ? "closing" : "open"}`;
|
const composerPopoverKey = `${menuToRender}-${cloneOutput}-${popoverClosingClass ? "closing" : "open"}`;
|
||||||
if (menuToRender === "assetLibrary") {
|
|
||||||
return (
|
|
||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--library${popoverClosingClass}`} style={composerPopoverStyle}>
|
|
||||||
{renderComposerAssetPanel()}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (menuToRender === "workMode") {
|
|
||||||
return (
|
|
||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--work-mode${popoverClosingClass}`} style={composerPopoverStyle}>
|
|
||||||
<header><strong>模式</strong><span>仅调整创作体验,不改变接口</span></header>
|
|
||||||
{composerWorkModeOptions.map((option) => (
|
|
||||||
<button key={option.key} type="button" className={composerWorkMode === option.key ? "is-active" : ""} onClick={() => { setComposerWorkMode(option.key); setComposerMenu(null); }}>
|
|
||||||
<strong>{option.label}</strong>
|
|
||||||
<span>{option.desc}</span>
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (menuToRender === "aiWrite") {
|
|
||||||
return (
|
|
||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--ai-write${popoverClosingClass}`} style={composerPopoverStyle}>
|
|
||||||
<header><strong>AI 帮写</strong><span>把关键词扩写成商业提示词</span></header>
|
|
||||||
<textarea value={aiWriteDraft} onChange={(event) => setAiWriteDraft(event.target.value.slice(0, 120))} placeholder="输入产品名称、卖点或期望风格" />
|
|
||||||
<button type="button" className="ecom-command-ai-submit" onClick={applyAiWriteSuggestion}>
|
|
||||||
开始智能优化
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (menuToRender === "mode") {
|
if (menuToRender === "mode") {
|
||||||
return (
|
return (
|
||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--grid ecom-command-popover--mode${popoverClosingClass}`} style={composerPopoverStyle}>
|
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--grid ecom-command-popover--mode${popoverClosingClass}`} style={composerPopoverStyle}>
|
||||||
@@ -6067,10 +5853,11 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
}
|
}
|
||||||
if (menuToRender === "platform") {
|
if (menuToRender === "platform") {
|
||||||
return (
|
return (
|
||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--list ecom-command-popover--platforms${popoverClosingClass}`} style={composerPopoverStyle}>
|
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--list ecom-command-popover--ratio ecom-command-popover--platform${popoverClosingClass}`} style={composerPopoverStyle}>
|
||||||
{platformOptions.map((option) => (
|
{platformOptions.map((option) => (
|
||||||
<button key={option} type="button" className={platform === option ? "is-active" : ""} onClick={() => { handleClonePlatformChange(option); setComposerMenu(null); }}>
|
<button key={option} type="button" className={platform === option ? "is-active" : ""} onClick={() => { handleClonePlatformChange(option); setComposerMenu(null); }}>
|
||||||
{option}
|
{renderPlatformLogo(option)}
|
||||||
|
<span className="ecom-platform-name">{option}</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -6081,7 +5868,8 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--languages${popoverClosingClass}`} style={composerPopoverStyle}>
|
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--languages${popoverClosingClass}`} style={composerPopoverStyle}>
|
||||||
{composerLanguageOptions.map((option) => (
|
{composerLanguageOptions.map((option) => (
|
||||||
<button key={option.language} type="button" className={language === option.language ? "is-active" : ""} onClick={() => { setLanguage(option.language); setComposerMenu(null); }}>
|
<button key={option.language} type="button" className={language === option.language ? "is-active" : ""} onClick={() => { setLanguage(option.language); setComposerMenu(null); }}>
|
||||||
{option.language}
|
<strong>{option.language}</strong>
|
||||||
|
<span>({option.countries.slice(0, 3).join(" / ")}{option.countries.length > 3 ? " +" + String(option.countries.length - 3) : ""})</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -6090,28 +5878,23 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
if (menuToRender === "ratio") {
|
if (menuToRender === "ratio") {
|
||||||
return (
|
return (
|
||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--list ecom-command-popover--ratio-picker${popoverClosingClass}`} style={composerPopoverStyle}>
|
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--list ecom-command-popover--ratio-picker${popoverClosingClass}`} style={composerPopoverStyle}>
|
||||||
{composerRatioOptions.map((option) => {
|
{cloneRatioOptions.map((option) => {
|
||||||
const ratioParts = getRatioDisplayParts(option);
|
const ratioParts = getRatioDisplayParts(option);
|
||||||
return (
|
return (
|
||||||
<button key={option} type="button" className={ratio === option ? "is-active" : ""} onClick={() => { setRatio(option); setComposerMenu(null); }}>
|
<button key={option} type="button" className={ratio === option ? "is-active" : ""} onClick={() => { setRatio(option); setComposerMenu(null); }}>
|
||||||
{ratioParts.aspect}
|
<span className="ecom-command-ratio-icon" aria-hidden="true">
|
||||||
|
<TableOutlined />
|
||||||
|
</span>
|
||||||
|
<span className="ecom-command-ratio-copy">
|
||||||
|
<strong>{ratioParts.size}</strong>
|
||||||
|
<em>{ratioParts.aspect}</em>
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (menuToRender === "settings" && activeCommerceScenario === "salesVideo") {
|
|
||||||
return (
|
|
||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--list ecom-command-popover--duration${popoverClosingClass}`} style={composerPopoverStyle}>
|
|
||||||
{composerDurationOptions.map((option) => (
|
|
||||||
<button key={option} type="button" className={cloneVideoDuration === option ? "is-active" : ""} onClick={() => { setCloneVideoDuration(option); setComposerMenu(null); }}>
|
|
||||||
{option}秒
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--settings ecom-command-popover--settings-${cloneOutput}${popoverClosingClass}`} style={composerPopoverStyle}>
|
<div key={composerPopoverKey} className={`ecom-command-popover ecom-command-popover--settings ecom-command-popover--settings-${cloneOutput}${popoverClosingClass}`} style={composerPopoverStyle}>
|
||||||
{cloneOutput === "set" ? (
|
{cloneOutput === "set" ? (
|
||||||
@@ -6699,33 +6482,24 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{shouldShowScenarioSettings ? (
|
<div className="ecom-command-option-row ecom-command-option-row--settings">
|
||||||
<div className="ecom-command-option-row ecom-command-option-row--settings">
|
<button type="button" className={composerMenu === "platform" ? "is-active" : ""} onClick={(event) => toggleComposerMenu("platform", event)}>
|
||||||
{activeCommerceScenario !== "salesVideo" && activeCommerceScenario !== "poster" ? (
|
<span className="ecom-command-option-icon" aria-hidden="true"><GlobalOutlined /></span>
|
||||||
<button type="button" className={composerMenu === "platform" ? "is-active" : ""} onClick={(event) => toggleComposerMenu("platform", event)}>
|
<span>平台</span>{platform}
|
||||||
<span className="ecom-command-option-icon" aria-hidden="true"><GlobalOutlined /></span>
|
</button>
|
||||||
<span>平台</span>{platform}
|
<button type="button" className={composerMenu === "language" ? "is-active" : ""} onClick={(event) => toggleComposerMenu("language", event)}>
|
||||||
</button>
|
<span className="ecom-command-option-icon" aria-hidden="true"><FileImageOutlined /></span>
|
||||||
) : null}
|
<span>语种</span>{language}
|
||||||
{activeCommerceScenario !== "salesVideo" ? (
|
</button>
|
||||||
<button type="button" className={composerMenu === "language" ? "is-active" : ""} onClick={(event) => toggleComposerMenu("language", event)}>
|
<button type="button" className={composerMenu === "ratio" ? "is-active" : ""} onClick={(event) => toggleComposerMenu("ratio", event)}>
|
||||||
<span className="ecom-command-option-icon" aria-hidden="true"><FileImageOutlined /></span>
|
<span className="ecom-command-option-icon" aria-hidden="true"><TableOutlined /></span>
|
||||||
<span>语种</span>{language}
|
<span>比例</span>{formatRatioDisplayValue(ratio)}
|
||||||
</button>
|
</button>
|
||||||
) : null}
|
<button type="button" className={composerMenu === "settings" ? "is-active" : ""} onClick={(event) => toggleComposerMenu("settings", event)}>
|
||||||
<button type="button" className={composerMenu === "ratio" ? "is-active" : ""} onClick={(event) => toggleComposerMenu("ratio", event)}>
|
<span className="ecom-command-option-icon" aria-hidden="true"><SettingOutlined /></span>
|
||||||
<span className="ecom-command-option-icon" aria-hidden="true"><TableOutlined /></span>
|
<span>设置</span>{composerSettingLabel}
|
||||||
<span>比例</span>{getRatioDisplayParts(ratio).aspect}
|
</button>
|
||||||
</button>
|
</div>
|
||||||
{scenarioAdvancedSettingsKeys.includes(activeCommerceScenario) ? (
|
|
||||||
<button type="button" className={composerMenu === "settings" ? "is-active" : ""} onClick={(event) => toggleComposerMenu("settings", event)}>
|
|
||||||
<span className="ecom-command-option-icon" aria-hidden="true"><SettingOutlined /></span>
|
|
||||||
<span>{activeCommerceScenario === "salesVideo" ? "时长" : "设置"}</span>
|
|
||||||
{activeCommerceScenario === "salesVideo" ? `${cloneVideoDuration}秒` : composerSettingLabel}
|
|
||||||
</button>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
<textarea
|
<textarea
|
||||||
ref={requirementTextareaRef}
|
ref={requirementTextareaRef}
|
||||||
value={requirement}
|
value={requirement}
|
||||||
@@ -6749,7 +6523,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
<div className="ecom-command-composer-actions">
|
<div className="ecom-command-composer-actions">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`ecom-command-reference ecom-command-reference--bottom ecom-command-tool ecom-command-tool--upload${productImages.length ? " has-images" : ""}${isProductUploadDragging ? " is-dragging" : ""}`}
|
className={`ecom-command-reference ecom-command-reference--bottom${productImages.length ? " has-images" : ""}${isProductUploadDragging ? " is-dragging" : ""}`}
|
||||||
onClick={() => productInputRef.current?.click()}
|
onClick={() => productInputRef.current?.click()}
|
||||||
onDragEnter={(event) => {
|
onDragEnter={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -6763,71 +6537,18 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
const files = Array.from(event.dataTransfer.files);
|
const files = Array.from(event.dataTransfer.files);
|
||||||
if (files.length) addComposerAssets(files);
|
if (files.length) addComposerAssets(files);
|
||||||
}}
|
}}
|
||||||
aria-label="上传素材"
|
|
||||||
title="上传素材"
|
|
||||||
>
|
>
|
||||||
<span aria-hidden="true"><PaperClipOutlined /></span>
|
<span aria-hidden="true"><PaperClipOutlined /></span>
|
||||||
<strong>上传素材</strong>
|
<strong>上传素材</strong>
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`ecom-command-tool ecom-command-tool--icon${composerMenu === "assetLibrary" ? " is-active" : ""}`}
|
|
||||||
onClick={(event) => toggleComposerMenu("assetLibrary", event)}
|
|
||||||
onMouseEnter={(event) => {
|
|
||||||
const rect = event.currentTarget.getBoundingClientRect();
|
|
||||||
setComposerTooltip({ text: "资产库", left: rect.left + rect.width / 2, top: rect.top - 8 });
|
|
||||||
}}
|
|
||||||
onMouseLeave={() => setComposerTooltip(null)}
|
|
||||||
aria-label="资产库"
|
|
||||||
title="资产库"
|
|
||||||
data-tooltip="资产库"
|
|
||||||
>
|
|
||||||
<FolderOpenOutlined />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`ecom-command-tool ecom-command-tool--icon${composerMenu === "workMode" ? " is-active" : ""}`}
|
|
||||||
onClick={(event) => toggleComposerMenu("workMode", event)}
|
|
||||||
onMouseEnter={(event) => {
|
|
||||||
const rect = event.currentTarget.getBoundingClientRect();
|
|
||||||
setComposerTooltip({ text: `模式:${composerWorkMode === "quick" ? "快捷" : "思考"}`, left: rect.left + rect.width / 2, top: rect.top - 8 });
|
|
||||||
}}
|
|
||||||
onMouseLeave={() => setComposerTooltip(null)}
|
|
||||||
aria-label={`模式:${composerWorkMode === "quick" ? "快捷" : "思考"}`}
|
|
||||||
title={`模式:${composerWorkMode === "quick" ? "快捷" : "思考"}`}
|
|
||||||
data-tooltip={`模式:${composerWorkMode === "quick" ? "快捷" : "思考"}`}
|
|
||||||
>
|
|
||||||
<ArrowsCounterClockwise size={17} weight="bold" />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`ecom-command-tool ecom-command-tool--icon${composerMenu === "aiWrite" ? " is-active" : ""}`}
|
|
||||||
onClick={(event) => toggleComposerMenu("aiWrite", event)}
|
|
||||||
onMouseEnter={(event) => {
|
|
||||||
const rect = event.currentTarget.getBoundingClientRect();
|
|
||||||
setComposerTooltip({ text: "AI帮写", left: rect.left + rect.width / 2, top: rect.top - 8 });
|
|
||||||
}}
|
|
||||||
onMouseLeave={() => setComposerTooltip(null)}
|
|
||||||
aria-label="AI帮写"
|
|
||||||
title="AI帮写"
|
|
||||||
data-tooltip="AI帮写"
|
|
||||||
>
|
|
||||||
<MagicWand size={17} weight="bold" />
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="ecom-command-submit-row">
|
<div className="ecom-command-submit-row">
|
||||||
<button type="button" className="clone-ai-send-button ecom-command-send" disabled={commandGenerateDisabled} onClick={handleCommandGenerate} aria-label={clonePrimaryLabel}>
|
<button type="button" className="clone-ai-send-button ecom-command-send" disabled={commandGenerateDisabled} onClick={handleCommandGenerate} aria-label={clonePrimaryLabel}>
|
||||||
{status === "generating" ? <LoadingOutlined /> : <PaperPlaneRight size={18} weight="fill" />}
|
{status === "generating" ? <LoadingOutlined /> : "➤"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{renderComposerMenu()}
|
{renderComposerMenu()}
|
||||||
{composerTooltip ? createPortal(
|
|
||||||
<span className="ecom-command-tooltip-floating" style={{ left: composerTooltip.left, top: composerTooltip.top }}>
|
|
||||||
{composerTooltip.text}
|
|
||||||
</span>,
|
|
||||||
document.body
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
{(status === "idle" || status === "ready") && !showMainVideoWorkspace && activeCommerceScenario !== null && isCloneTemplateStripVisible ? (
|
{(status === "idle" || status === "ready") && !showMainVideoWorkspace && activeCommerceScenario !== null && isCloneTemplateStripVisible ? (
|
||||||
<div className={`ecom-command-template-carousel ecom-command-template-carousel--${activeCommerceScenario}`}>
|
<div className={`ecom-command-template-carousel ecom-command-template-carousel--${activeCommerceScenario}`}>
|
||||||
@@ -6888,6 +6609,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
{ label: "图片翻译", tone: "translate", icon: <GlobalOutlined />, onClick: openImageTranslatePage },
|
{ label: "图片翻译", tone: "translate", icon: <GlobalOutlined />, onClick: openImageTranslatePage },
|
||||||
{ label: "商品套图", tone: "product", icon: <AppstoreOutlined />, onClick: openQuickSetPage },
|
{ label: "商品套图", tone: "product", icon: <AppstoreOutlined />, onClick: openQuickSetPage },
|
||||||
{ label: "一键文案", tone: "copywriting", icon: <EditOutlined />, onClick: openCopywritingPage },
|
{ label: "一键文案", tone: "copywriting", icon: <EditOutlined />, onClick: openCopywritingPage },
|
||||||
|
{ label: "一键视频", tone: "video", icon: <VideoCameraOutlined />, onClick: openOneClickVideoPage },
|
||||||
{ label: "更多功能", tone: "more", icon: <SettingOutlined />, disabled: true },
|
{ label: "更多功能", tone: "more", icon: <SettingOutlined />, disabled: true },
|
||||||
].map((item) => (
|
].map((item) => (
|
||||||
<button
|
<button
|
||||||
@@ -8731,6 +8453,42 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const oneClickVideoPreview = (
|
||||||
|
<div key="oneClickVideo" className="ecom-quick-page-wrap ecom-tool-page-enter">
|
||||||
|
<EcommerceOneClickVideoPanel
|
||||||
|
onClose={closeOneClickVideoPage}
|
||||||
|
isAuthenticated={isAuthenticated}
|
||||||
|
onRequestLogin={requestLogin}
|
||||||
|
productImages={productImages}
|
||||||
|
productInputRef={productInputRef}
|
||||||
|
isProductUploadDragging={isProductUploadDragging}
|
||||||
|
setIsProductUploadDragging={setIsProductUploadDragging}
|
||||||
|
handleProductDrop={handleProductDrop}
|
||||||
|
handleProductUpload={handleProductUpload}
|
||||||
|
removeProductImage={removeProductImage}
|
||||||
|
maxProductImages={maxCloneProductImages}
|
||||||
|
requirement={requirement}
|
||||||
|
onRequirementChange={setRequirement}
|
||||||
|
platform={platform}
|
||||||
|
platformOptions={platformOptions}
|
||||||
|
onPlatformChange={handleOneClickVideoPlatformChange}
|
||||||
|
ratio={ratio}
|
||||||
|
ratioOptions={getPlatformRatioOptions(platform, "video")}
|
||||||
|
onRatioChange={setRatio}
|
||||||
|
videoQuality={cloneVideoQuality}
|
||||||
|
videoQualityOptions={cloneVideoQualityOptions}
|
||||||
|
onVideoQualityChange={setCloneVideoQuality}
|
||||||
|
videoDuration={cloneVideoDuration}
|
||||||
|
videoDurationMin={cloneVideoDurationMin}
|
||||||
|
videoDurationMax={cloneVideoDurationMax}
|
||||||
|
onVideoDurationChange={setCloneVideoDuration}
|
||||||
|
videoSmart={cloneVideoSmart}
|
||||||
|
onVideoSmartChange={setCloneVideoSmart}
|
||||||
|
onOpenHistory={() => setVideoHistoryVisible(true)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const activePreview = isSetTool
|
const activePreview = isSetTool
|
||||||
? setPreview
|
? setPreview
|
||||||
: isDetail
|
: isDetail
|
||||||
@@ -8766,9 +8524,11 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
)
|
)
|
||||||
: isCopywritingTool
|
: isCopywritingTool
|
||||||
? copywritingPreview
|
? copywritingPreview
|
||||||
: clonePreview
|
: isOneClickVideoTool
|
||||||
|
? oneClickVideoPreview
|
||||||
|
: clonePreview
|
||||||
: placeholderPreview;
|
: placeholderPreview;
|
||||||
const isMainCloneWorkspace = isCloneTool && !isSmartCutoutTool && !isQuickDetailTool && !isWatermarkTool && !isTranslateTool && !isImageEditTool && !isQuickSetTool && !isCopywritingTool;
|
const isMainCloneWorkspace = isCloneTool && !isSmartCutoutTool && !isQuickDetailTool && !isWatermarkTool && !isTranslateTool && !isImageEditTool && !isQuickSetTool && !isCopywritingTool && !isOneClickVideoTool;
|
||||||
const isRecordDetailWorkspace = isMainCloneWorkspace && Boolean(activeHistoryRecordId);
|
const isRecordDetailWorkspace = isMainCloneWorkspace && Boolean(activeHistoryRecordId);
|
||||||
const currentResultCount = canvasNodes.reduce((count, node) => count + node.results.length, 0);
|
const currentResultCount = canvasNodes.reduce((count, node) => count + node.results.length, 0);
|
||||||
const activeHistoryRecord = activeHistoryRecordId ? ecommerceHistoryRecords.find((record) => record.id === activeHistoryRecordId) : null;
|
const activeHistoryRecord = activeHistoryRecordId ? ecommerceHistoryRecords.find((record) => record.id === activeHistoryRecordId) : null;
|
||||||
@@ -8804,7 +8564,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
className={`product-clone-page page-motion${isCloneTool && isCloneSettingsCollapsed ? " is-settings-collapsed" : ""}${isCloneTool && isCommandHistoryCollapsed ? " is-history-collapsed" : ""}${isRecordDetailWorkspace && isCloneConversationCollapsed ? " is-conversation-collapsed" : ""}${isRecordDetailWorkspace ? " is-history-detail" : ""}${isSmartCutoutTool ? " is-smart-cutout-page" : ""}${isQuickDetailTool ? " is-quick-set-page" : ""}${isWatermarkTool ? " is-watermark-page" : ""}${isTranslateTool ? " is-translate-page" : ""}${isImageEditTool ? " is-image-workbench-page" : ""}${isHotCloneTool ? " is-hot-clone-page" : ""}${isQuickSetTool ? " is-quick-set-page" : ""}${isCopywritingTool ? " is-copywriting-page" : ""}`}
|
className={`product-clone-page page-motion${isCloneTool && isCloneSettingsCollapsed ? " is-settings-collapsed" : ""}${isCloneTool && isCommandHistoryCollapsed ? " is-history-collapsed" : ""}${isRecordDetailWorkspace && isCloneConversationCollapsed ? " is-conversation-collapsed" : ""}${isRecordDetailWorkspace ? " is-history-detail" : ""}${isSmartCutoutTool ? " is-smart-cutout-page" : ""}${isQuickDetailTool ? " is-quick-set-page" : ""}${isWatermarkTool ? " is-watermark-page" : ""}${isTranslateTool ? " is-translate-page" : ""}${isImageEditTool ? " is-image-workbench-page" : ""}${isHotCloneTool ? " is-hot-clone-page" : ""}${isQuickSetTool ? " is-quick-set-page" : ""}${isCopywritingTool ? " is-copywriting-page" : ""}${isOneClickVideoTool ? " is-one-click-video-page" : ""}`}
|
||||||
data-tool={activeTool}
|
data-tool={activeTool}
|
||||||
aria-label={pageLabel}
|
aria-label={pageLabel}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -0,0 +1,408 @@
|
|||||||
|
import {
|
||||||
|
FileImageOutlined,
|
||||||
|
PlusOutlined,
|
||||||
|
ThunderboltOutlined,
|
||||||
|
VideoCameraOutlined,
|
||||||
|
} from "@ant-design/icons";
|
||||||
|
import { useMemo, useRef, useState, type ChangeEvent, type DragEvent, type KeyboardEvent, type RefObject } from "react";
|
||||||
|
import EcommerceVideoWorkspace from "../EcommerceVideoWorkspace";
|
||||||
|
|
||||||
|
interface CloneImageItem {
|
||||||
|
id: string;
|
||||||
|
src: string;
|
||||||
|
name: string;
|
||||||
|
file?: File;
|
||||||
|
}
|
||||||
|
|
||||||
|
type CloneVideoQualityKey = "standard" | "high" | "ultra";
|
||||||
|
|
||||||
|
interface EcommerceOneClickVideoPanelProps {
|
||||||
|
onClose: () => void;
|
||||||
|
isAuthenticated: boolean;
|
||||||
|
onRequestLogin: () => void;
|
||||||
|
productImages: CloneImageItem[];
|
||||||
|
productInputRef: RefObject<HTMLInputElement>;
|
||||||
|
isProductUploadDragging: boolean;
|
||||||
|
setIsProductUploadDragging: (value: boolean) => void;
|
||||||
|
handleProductDrop: (event: DragEvent<HTMLDivElement>) => void;
|
||||||
|
handleProductUpload: (event: ChangeEvent<HTMLInputElement>) => void;
|
||||||
|
removeProductImage: (imageId: string) => void;
|
||||||
|
maxProductImages: number;
|
||||||
|
requirement: string;
|
||||||
|
onRequirementChange: (value: string) => void;
|
||||||
|
platform: string;
|
||||||
|
platformOptions: string[];
|
||||||
|
onPlatformChange: (value: string) => void;
|
||||||
|
ratio: string;
|
||||||
|
ratioOptions: string[];
|
||||||
|
onRatioChange: (value: string) => void;
|
||||||
|
videoQuality: CloneVideoQualityKey;
|
||||||
|
videoQualityOptions: Array<{ key: CloneVideoQualityKey; label: string; desc: string }>;
|
||||||
|
onVideoQualityChange: (value: CloneVideoQualityKey) => void;
|
||||||
|
videoDuration: number;
|
||||||
|
videoDurationMin: number;
|
||||||
|
videoDurationMax: number;
|
||||||
|
onVideoDurationChange: (value: number) => void;
|
||||||
|
videoSmart: boolean;
|
||||||
|
onVideoSmartChange: (value: boolean) => void;
|
||||||
|
onOpenHistory: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVideoAspectRatio(ratio: string): string {
|
||||||
|
if (ratio.includes("9:16")) return "9:16";
|
||||||
|
if (ratio.includes("16:9")) return "16:9";
|
||||||
|
if (ratio.includes("3:4")) return "3:4";
|
||||||
|
return "9:16";
|
||||||
|
}
|
||||||
|
|
||||||
|
function openQuickUploadWithKeyboard(
|
||||||
|
event: KeyboardEvent<HTMLDivElement>,
|
||||||
|
inputRef: { current: HTMLInputElement | null },
|
||||||
|
) {
|
||||||
|
if (event.key !== "Enter" && event.key !== " ") return;
|
||||||
|
event.preventDefault();
|
||||||
|
inputRef.current?.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function EcommerceOneClickVideoPanel({
|
||||||
|
onClose,
|
||||||
|
isAuthenticated,
|
||||||
|
onRequestLogin,
|
||||||
|
productImages,
|
||||||
|
productInputRef,
|
||||||
|
isProductUploadDragging,
|
||||||
|
setIsProductUploadDragging,
|
||||||
|
handleProductDrop,
|
||||||
|
handleProductUpload,
|
||||||
|
removeProductImage,
|
||||||
|
maxProductImages,
|
||||||
|
requirement,
|
||||||
|
onRequirementChange,
|
||||||
|
platform,
|
||||||
|
platformOptions,
|
||||||
|
onPlatformChange,
|
||||||
|
ratio,
|
||||||
|
ratioOptions,
|
||||||
|
onRatioChange,
|
||||||
|
videoQuality,
|
||||||
|
videoQualityOptions,
|
||||||
|
onVideoQualityChange,
|
||||||
|
videoDuration,
|
||||||
|
videoDurationMin,
|
||||||
|
videoDurationMax,
|
||||||
|
onVideoDurationChange,
|
||||||
|
videoSmart,
|
||||||
|
onVideoSmartChange,
|
||||||
|
onOpenHistory,
|
||||||
|
}: EcommerceOneClickVideoPanelProps) {
|
||||||
|
const [openSelect, setOpenSelect] = useState<"platform" | "ratio" | null>(null);
|
||||||
|
const [planTrigger, setPlanTrigger] = useState(0);
|
||||||
|
const selectAnchorRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const productImageDataUrls = useMemo(() => productImages.map((img) => img.src), [productImages]);
|
||||||
|
const productImageFiles = useMemo(() => productImages.map((img) => img.file), [productImages]);
|
||||||
|
|
||||||
|
const canGenerate = productImages.length > 0 || requirement.trim().length > 0;
|
||||||
|
|
||||||
|
const handleGenerate = () => {
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
onRequestLogin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPlanTrigger((value) => value + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePlatformSelect = (value: string) => {
|
||||||
|
onPlatformChange(value);
|
||||||
|
setOpenSelect(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRatioSelect = (value: string) => {
|
||||||
|
onRatioChange(value);
|
||||||
|
setOpenSelect(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleSelect = (key: "platform" | "ratio") => {
|
||||||
|
setOpenSelect((current) => (current === key ? null : key));
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderThumbs = () => (
|
||||||
|
<div className="ecom-quick-upload-thumbs" aria-label="已上传商品原图">
|
||||||
|
{productImages.map((item) => (
|
||||||
|
<figure key={item.id} className="ecom-command-asset-thumb ecom-quick-upload-thumb">
|
||||||
|
<img src={item.src} alt={item.name} />
|
||||||
|
<span className="ecom-command-asset-zoom" aria-hidden="true">
|
||||||
|
<img src={item.src} alt="" />
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label="删除图片"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
removeProductImage(item.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</figure>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="ecom-one-click-video-page ecom-quick-hot-page ecom-quick-set-page ecom-tool-page-enter" aria-label="一键视频">
|
||||||
|
<div className="ecom-quick-set-body">
|
||||||
|
<aside className="ecom-quick-set-panel" aria-label="一键视频设置">
|
||||||
|
<header className="ecom-quick-set-panel-head">
|
||||||
|
<strong className="ecom-quick-set-page-title">
|
||||||
|
<VideoCameraOutlined /> 一键视频
|
||||||
|
</strong>
|
||||||
|
<button type="button" className="ecom-quick-set-back" onClick={onClose}>
|
||||||
|
首页
|
||||||
|
</button>
|
||||||
|
<button type="button" className="ecom-quick-set-back" onClick={onClose}>
|
||||||
|
上一页
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<strong><FileImageOutlined /> 上传商品原图</strong>
|
||||||
|
{productImages.length ? (
|
||||||
|
<div
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
className={`ecom-quick-set-upload ecom-quick-hot-material has-images${isProductUploadDragging ? " is-dragging" : ""}`}
|
||||||
|
onClick={() => productInputRef.current?.click()}
|
||||||
|
onKeyDown={(event) => openQuickUploadWithKeyboard(event, productInputRef)}
|
||||||
|
onDragOver={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
if (event.dataTransfer.types.includes("Files")) setIsProductUploadDragging(true);
|
||||||
|
}}
|
||||||
|
onDragLeave={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
if (event.currentTarget === event.target || !event.currentTarget.contains(event.relatedTarget as Node)) {
|
||||||
|
setIsProductUploadDragging(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onDrop={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
setIsProductUploadDragging(false);
|
||||||
|
handleProductDrop(event);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{renderThumbs()}
|
||||||
|
{productImages.length < maxProductImages ? (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ecom-quick-hot-add-btn"
|
||||||
|
aria-label="添加更多素材"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
productInputRef.current?.click();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PlusOutlined />
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
className={`ecom-quick-set-upload ecom-quick-hot-material${isProductUploadDragging ? " is-dragging" : ""}`}
|
||||||
|
onClick={() => productInputRef.current?.click()}
|
||||||
|
onKeyDown={(event) => openQuickUploadWithKeyboard(event, productInputRef)}
|
||||||
|
onDragOver={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
if (event.dataTransfer.types.includes("Files")) setIsProductUploadDragging(true);
|
||||||
|
}}
|
||||||
|
onDragLeave={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
if (event.currentTarget === event.target || !event.currentTarget.contains(event.relatedTarget as Node)) {
|
||||||
|
setIsProductUploadDragging(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onDrop={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
setIsProductUploadDragging(false);
|
||||||
|
handleProductDrop(event);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FileImageOutlined />
|
||||||
|
<span>拖拽或点击上传</span>
|
||||||
|
<em>上传商品素材图,最多 {maxProductImages} 张</em>
|
||||||
|
<b>+ 上传图片</b>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<input
|
||||||
|
ref={productInputRef}
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
multiple
|
||||||
|
className="ecom-command-hidden-file"
|
||||||
|
onChange={handleProductUpload}
|
||||||
|
aria-label="上传商品图片"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="ecom-quick-hot-requirement">
|
||||||
|
<div className="ecom-quick-hot-requirement__head">
|
||||||
|
<strong>视频需求</strong>
|
||||||
|
</div>
|
||||||
|
<div className="ecom-quick-hot-requirement__input">
|
||||||
|
<textarea
|
||||||
|
value={requirement}
|
||||||
|
onChange={(event) => onRequirementChange(event.target.value.slice(0, 500))}
|
||||||
|
placeholder="建议包含以下信息:产品名称、核心卖点、期望场景、口播风格、具体参数"
|
||||||
|
maxLength={500}
|
||||||
|
rows={4}
|
||||||
|
/>
|
||||||
|
<span>{requirement.length}/500</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="ecom-quick-set-basic-section">
|
||||||
|
<span className="ecom-quick-set-label">基础设置</span>
|
||||||
|
<div className="ecom-quick-set-select-anchor" ref={selectAnchorRef}>
|
||||||
|
<div className="ecom-quick-set-selects">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={openSelect === "platform" ? "is-active" : ""}
|
||||||
|
onClick={() => toggleSelect("platform")}
|
||||||
|
>
|
||||||
|
<span>平台</span>
|
||||||
|
<strong>{platform}</strong>
|
||||||
|
<em>⌄</em>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={openSelect === "ratio" ? "is-active" : ""}
|
||||||
|
onClick={() => toggleSelect("ratio")}
|
||||||
|
>
|
||||||
|
<span>尺寸比例</span>
|
||||||
|
<strong>{ratio.replace(/\s+/g, " ").trim()}</strong>
|
||||||
|
<em>⌄</em>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{openSelect ? (
|
||||||
|
<div
|
||||||
|
className="ecom-quick-set-dropdown"
|
||||||
|
role="listbox"
|
||||||
|
aria-label={openSelect === "platform" ? "平台" : "尺寸比例"}
|
||||||
|
>
|
||||||
|
{(openSelect === "platform" ? platformOptions : ratioOptions).map((option) => (
|
||||||
|
<button
|
||||||
|
key={option}
|
||||||
|
type="button"
|
||||||
|
className={
|
||||||
|
(openSelect === "platform" ? platform === option : ratio === option) ? "is-active" : ""
|
||||||
|
}
|
||||||
|
role="option"
|
||||||
|
aria-selected={openSelect === "platform" ? platform === option : ratio === option}
|
||||||
|
onClick={() => {
|
||||||
|
if (openSelect === "platform") {
|
||||||
|
handlePlatformSelect(option);
|
||||||
|
} else {
|
||||||
|
handleRatioSelect(option);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{option.replace(/\s+/g, " ").trim()}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<strong>视频画质</strong>
|
||||||
|
<div className="ecom-quick-detail-modules">
|
||||||
|
{videoQualityOptions.map((option) => (
|
||||||
|
<button
|
||||||
|
key={option.key}
|
||||||
|
type="button"
|
||||||
|
className={videoQuality === option.key ? "is-active" : ""}
|
||||||
|
aria-pressed={videoQuality === option.key}
|
||||||
|
onClick={() => onVideoQualityChange(option.key)}
|
||||||
|
>
|
||||||
|
<strong>{option.label}</strong>
|
||||||
|
<span>{option.desc}</span>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<strong>视频时长</strong>
|
||||||
|
<div className="ecom-one-click-video-duration">
|
||||||
|
<span>{videoDuration} 秒</span>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
className="ecom-one-click-video-range"
|
||||||
|
min={videoDurationMin}
|
||||||
|
max={videoDurationMax}
|
||||||
|
step={5}
|
||||||
|
value={videoDuration}
|
||||||
|
onChange={(event) => onVideoDurationChange(Number(event.target.value))}
|
||||||
|
aria-label="视频时长"
|
||||||
|
/>
|
||||||
|
<div className="ecom-one-click-video-duration-scale" aria-hidden="true">
|
||||||
|
<span>{videoDurationMin}秒</span>
|
||||||
|
<span>{videoDurationMax}秒</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`ecom-one-click-video-smart${videoSmart ? " is-on" : ""}`}
|
||||||
|
aria-pressed={videoSmart}
|
||||||
|
onClick={() => onVideoSmartChange(!videoSmart)}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<strong>智能优化</strong>
|
||||||
|
<em>根据平台、商品图和尺寸自动匹配推荐参数</em>
|
||||||
|
</span>
|
||||||
|
<i aria-hidden="true" />
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="ecom-quick-hot-actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ecom-quick-set-primary ecom-one-click-video-generate"
|
||||||
|
onClick={handleGenerate}
|
||||||
|
disabled={!canGenerate}
|
||||||
|
>
|
||||||
|
<ThunderboltOutlined /> {isAuthenticated ? "一键生成视频" : "登录后生成"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<section className="ecom-quick-set-stage">
|
||||||
|
<EcommerceVideoWorkspace
|
||||||
|
isAuthenticated={isAuthenticated}
|
||||||
|
productImageDataUrls={productImageDataUrls}
|
||||||
|
productImageFiles={productImageFiles}
|
||||||
|
requirement={requirement}
|
||||||
|
platform={platform}
|
||||||
|
aspectRatio={getVideoAspectRatio(ratio)}
|
||||||
|
durationSeconds={videoDuration}
|
||||||
|
resolution={videoQuality === "standard" ? "720P" : "1080P"}
|
||||||
|
onRequestLogin={onRequestLogin}
|
||||||
|
onOpenHistory={onOpenHistory}
|
||||||
|
triggerPlan={planTrigger}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
+239
-1207
File diff suppressed because it is too large
Load Diff
+30
-643
@@ -3047,47 +3047,33 @@
|
|||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
background: #1b1d23;
|
background: #1b1d23;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
transition:
|
|
||||||
border-color 180ms ease,
|
|
||||||
box-shadow 180ms ease,
|
|
||||||
transform 180ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper:focus-within {
|
|
||||||
border-color: rgba(0, 255, 136, 0.45);
|
|
||||||
box-shadow:
|
|
||||||
0 0 0 1px rgba(0, 255, 136, 0.08),
|
|
||||||
0 18px 46px rgba(0, 0, 0, 0.32);
|
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-send-button {
|
.product-clone-page[data-tool="clone"] .clone-ai-send-button {
|
||||||
display: inline-flex;
|
display: grid;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 38px;
|
width: 38px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
|
place-items: center;
|
||||||
border: 1px solid #303540;
|
border: 1px solid #303540;
|
||||||
border-radius: 12px;
|
border-radius: 999px;
|
||||||
background: #00ff88;
|
background: #22252d;
|
||||||
color: #06130d;
|
color: #eef2f6;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 900;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition:
|
transition:
|
||||||
background-color 160ms ease,
|
background-color 160ms ease,
|
||||||
border-color 160ms ease,
|
border-color 160ms ease,
|
||||||
transform 160ms ease,
|
transform 160ms ease;
|
||||||
box-shadow 160ms ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-send-button:hover:not(:disabled) {
|
.product-clone-page[data-tool="clone"] .clone-ai-send-button:hover:not(:disabled) {
|
||||||
border-color: #00ff88;
|
border-color: #00ff88;
|
||||||
background: #00ff88;
|
background: #202c28;
|
||||||
box-shadow: 0 10px 24px rgba(0, 255, 136, 0.24);
|
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-send-button:active:not(:disabled) {
|
.product-clone-page[data-tool="clone"] .clone-ai-send-button:active:not(:disabled) {
|
||||||
transform: translateY(0) scale(0.96);
|
transform: scale(0.94);
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper textarea {
|
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper textarea {
|
||||||
@@ -3096,7 +3082,7 @@
|
|||||||
max-height: 183px;
|
max-height: 183px;
|
||||||
border: 0;
|
border: 0;
|
||||||
outline: none;
|
outline: none;
|
||||||
resize: none;
|
resize: vertical;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: #eef2f6;
|
color: #eef2f6;
|
||||||
padding: 10px 0 8px;
|
padding: 10px 0 8px;
|
||||||
@@ -3107,15 +3093,17 @@
|
|||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper textarea::placeholder {
|
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper textarea::placeholder {
|
||||||
color: #687184;
|
color: #687184;
|
||||||
font-size: 13px;
|
}
|
||||||
font-weight: 400;
|
|
||||||
|
.product-clone-page[data-tool="clone"] .clone-ai-send-button {
|
||||||
|
background: #00ff88;
|
||||||
|
color: #06130d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-send-button:disabled {
|
.product-clone-page[data-tool="clone"] .clone-ai-send-button:disabled {
|
||||||
background: #26342f;
|
background: #26342f;
|
||||||
color: #677569;
|
color: #677569;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
opacity: 0.7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-char-count {
|
.product-clone-page[data-tool="clone"] .clone-ai-char-count {
|
||||||
@@ -8957,28 +8945,17 @@
|
|||||||
rgba(20, 24, 23, 0.92);
|
rgba(20, 24, 23, 0.92);
|
||||||
box-shadow: var(--ecm-shadow-panel);
|
box-shadow: var(--ecm-shadow-panel);
|
||||||
backdrop-filter: blur(18px);
|
backdrop-filter: blur(18px);
|
||||||
transition:
|
|
||||||
border-color 180ms ease,
|
|
||||||
box-shadow 180ms ease,
|
|
||||||
transform 180ms ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper:focus-within {
|
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper:focus-within {
|
||||||
border-color: rgba(var(--ecm-accent-rgb), 0.5);
|
border-color: rgba(var(--ecm-accent-rgb), 0.42);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 22px 62px rgba(0, 0, 0, 0.36),
|
0 20px 58px rgba(0, 0, 0, 0.34),
|
||||||
0 0 0 1px rgba(var(--ecm-accent-rgb), 0.1);
|
0 0 0 1px rgba(var(--ecm-accent-rgb), 0.08);
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper textarea {
|
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper textarea {
|
||||||
color: var(--ecm-text);
|
color: var(--ecm-text);
|
||||||
resize: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-input-wrapper textarea::placeholder {
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-clone-page[data-tool="clone"] .clone-ai-char-count {
|
.product-clone-page[data-tool="clone"] .clone-ai-char-count {
|
||||||
@@ -9868,14 +9845,10 @@
|
|||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-send {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-send {
|
||||||
position: static;
|
position: static;
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 46px;
|
width: 46px;
|
||||||
height: 46px;
|
height: 46px;
|
||||||
min-height: 46px;
|
min-height: 46px;
|
||||||
border: 1px solid rgba(var(--ecm-accent-rgb), 0.55);
|
border: 1px solid rgba(var(--ecm-accent-rgb), 0.55);
|
||||||
border-radius: 12px;
|
|
||||||
color: #021b2e;
|
color: #021b2e;
|
||||||
background: linear-gradient(135deg, #16c8df, #18a7ff);
|
background: linear-gradient(135deg, #16c8df, #18a7ff);
|
||||||
box-shadow: 0 12px 28px rgba(var(--ecm-accent-rgb), 0.32);
|
box-shadow: 0 12px 28px rgba(var(--ecm-accent-rgb), 0.32);
|
||||||
@@ -9883,12 +9856,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-send:hover:not(:disabled) {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-send:hover:not(:disabled) {
|
||||||
transform: translateY(-2px) scale(1.02);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 18px 38px rgba(var(--ecm-accent-rgb), 0.38);
|
box-shadow: 0 16px 34px rgba(var(--ecm-accent-rgb), 0.36);
|
||||||
}
|
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-send:active:not(:disabled) {
|
|
||||||
transform: translateY(0) scale(0.98);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-send:disabled {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-send:disabled {
|
||||||
@@ -9896,7 +9865,6 @@
|
|||||||
color: rgba(255, 255, 255, 0.26);
|
color: rgba(255, 255, 255, 0.26);
|
||||||
background: rgba(126, 235, 255, 0.08);
|
background: rgba(126, 235, 255, 0.08);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
opacity: 0.7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-char-count {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-char-count {
|
||||||
@@ -11085,17 +11053,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:focus-within {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:focus-within {
|
||||||
border-color: rgba(30, 189, 219, 0.5) !important;
|
border-color: var(--ecom-entry-line-strong) !important;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.96),
|
inset 0 1px 0 rgba(255, 255, 255, 0.92),
|
||||||
0 0 0 1px rgba(30, 189, 219, 0.08),
|
|
||||||
var(--ecom-entry-focus),
|
var(--ecom-entry-focus),
|
||||||
var(--ecom-entry-shadow-strong) !important;
|
var(--ecom-entry-shadow-strong) !important;
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:hover {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:hover {
|
||||||
border-color: rgba(30, 189, 219, 0.32) !important;
|
border-color: rgba(30, 189, 219, 0.3) !important;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.92),
|
inset 0 1px 0 rgba(255, 255, 255, 0.92),
|
||||||
0 26px 72px rgba(16, 115, 204, 0.13) !important;
|
0 26px 72px rgba(16, 115, 204, 0.13) !important;
|
||||||
@@ -11103,10 +11070,10 @@
|
|||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer.is-dragging,
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer.is-dragging,
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer.has-files {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer.has-files {
|
||||||
border-color: rgba(30, 189, 219, 0.5) !important;
|
border-color: rgba(30, 189, 219, 0.42) !important;
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(244, 253, 255, 0.96) 100%),
|
linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(244, 253, 255, 0.96) 100%),
|
||||||
linear-gradient(135deg, rgba(30, 189, 219, 0.12), rgba(16, 115, 204, 0.08)) !important;
|
linear-gradient(135deg, rgba(30, 189, 219, 0.1), rgba(16, 115, 204, 0.06)) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-reference {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-reference {
|
||||||
@@ -11147,11 +11114,8 @@
|
|||||||
caret-color: var(--ecom-entry-accent) !important;
|
caret-color: var(--ecom-entry-accent) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-input::placeholder,
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-input::placeholder {
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer textarea::placeholder {
|
color: rgba(16, 32, 44, 0.38) !important;
|
||||||
color: rgba(16, 32, 44, 0.42) !important;
|
|
||||||
font-size: 13px !important;
|
|
||||||
font-weight: 400 !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-toolbar {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-toolbar {
|
||||||
@@ -11236,16 +11200,11 @@
|
|||||||
box-shadow:
|
box-shadow:
|
||||||
0 20px 38px rgba(30, 189, 219, 0.34),
|
0 20px 38px rgba(30, 189, 219, 0.34),
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.42) !important;
|
inset 0 1px 0 rgba(255, 255, 255, 0.42) !important;
|
||||||
transform: translateY(-2px) scale(1.03);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-send-button.ecom-command-send:active:not(:disabled) {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-send-button.ecom-command-send:active:not(:disabled) {
|
||||||
transform: translateY(0) scale(0.97);
|
transform: translateY(1px) scale(0.98);
|
||||||
}
|
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-send-button.ecom-command-send:disabled {
|
|
||||||
opacity: 0.5 !important;
|
|
||||||
filter: grayscale(0.35) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-char-count {
|
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-char-count {
|
||||||
@@ -12250,575 +12209,3 @@ html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[d
|
|||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
font-size: 24px !important;
|
font-size: 24px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Final composer toolbelt overrides: keep upload/assets/mode/AI writing responsive and single-line. */
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-toolbar {
|
|
||||||
flex-direction: row !important;
|
|
||||||
align-items: center !important;
|
|
||||||
justify-content: space-between !important;
|
|
||||||
gap: 12px !important;
|
|
||||||
min-width: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-actions {
|
|
||||||
display: flex !important;
|
|
||||||
flex: 1 1 auto !important;
|
|
||||||
flex-wrap: nowrap !important;
|
|
||||||
align-items: center !important;
|
|
||||||
gap: 8px !important;
|
|
||||||
min-width: 0 !important;
|
|
||||||
overflow-x: auto !important;
|
|
||||||
overflow-y: visible !important;
|
|
||||||
padding: 2px !important;
|
|
||||||
scrollbar-width: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-actions::-webkit-scrollbar {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool {
|
|
||||||
position: relative !important;
|
|
||||||
flex: 0 0 auto !important;
|
|
||||||
display: inline-flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
justify-content: center !important;
|
|
||||||
height: 40px !important;
|
|
||||||
min-height: 40px !important;
|
|
||||||
border: 1px solid rgba(16, 32, 44, 0.08) !important;
|
|
||||||
border-radius: 999px !important;
|
|
||||||
color: rgba(16, 32, 44, 0.72) !important;
|
|
||||||
background: rgba(255, 255, 255, 0.82) !important;
|
|
||||||
box-shadow: 0 6px 18px rgba(16, 115, 204, 0.045), inset 0 1px 0 rgba(255, 255, 255, 0.96) !important;
|
|
||||||
cursor: pointer !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool:hover,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool.is-active,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool.has-images,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool.is-dragging {
|
|
||||||
border-color: rgba(30, 189, 219, 0.32) !important;
|
|
||||||
color: #0f829b !important;
|
|
||||||
background: rgba(232, 249, 253, 0.95) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--upload {
|
|
||||||
gap: 7px !important;
|
|
||||||
width: auto !important;
|
|
||||||
min-width: max-content !important;
|
|
||||||
padding: 0 13px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--icon {
|
|
||||||
width: 40px !important;
|
|
||||||
min-width: 40px !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--icon::after {
|
|
||||||
position: absolute !important;
|
|
||||||
left: 50% !important;
|
|
||||||
bottom: calc(100% + 10px) !important;
|
|
||||||
z-index: 260 !important;
|
|
||||||
padding: 6px 9px !important;
|
|
||||||
border-radius: 8px !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
background: rgba(16, 32, 44, 0.72) !important;
|
|
||||||
content: attr(data-tooltip) !important;
|
|
||||||
font-size: 12px !important;
|
|
||||||
font-weight: 760 !important;
|
|
||||||
line-height: 1 !important;
|
|
||||||
opacity: 0 !important;
|
|
||||||
pointer-events: none !important;
|
|
||||||
transform: translate(-50%, 4px) !important;
|
|
||||||
white-space: nowrap !important;
|
|
||||||
transition: opacity 150ms ease, transform 150ms ease !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--icon:hover::after,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--icon:focus-visible::after {
|
|
||||||
opacity: 1 !important;
|
|
||||||
transform: translate(-50%, 0) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--library,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ai-write {
|
|
||||||
gap: 14px !important;
|
|
||||||
border-color: rgba(16, 32, 44, 0.08) !important;
|
|
||||||
border-radius: 24px !important;
|
|
||||||
background: rgba(255, 255, 255, 0.98) !important;
|
|
||||||
box-shadow: 0 30px 76px rgba(16, 115, 204, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.92) !important;
|
|
||||||
color: #10202c !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover--library {
|
|
||||||
width: min(540px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
max-width: min(540px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
min-height: 300px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover--work-mode {
|
|
||||||
width: min(340px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
max-width: min(340px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover--ai-write {
|
|
||||||
width: min(430px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
max-width: min(430px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-head,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode header,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ai-write header {
|
|
||||||
display: flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
justify-content: space-between !important;
|
|
||||||
gap: 12px !important;
|
|
||||||
color: #10202c !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-head strong,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode header strong,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ai-write header strong {
|
|
||||||
color: #10202c !important;
|
|
||||||
font-size: 22px !important;
|
|
||||||
font-weight: 880 !important;
|
|
||||||
white-space: nowrap !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-help {
|
|
||||||
display: inline-flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
gap: 5px !important;
|
|
||||||
min-height: 28px !important;
|
|
||||||
padding: 0 8px !important;
|
|
||||||
border: 0 !important;
|
|
||||||
color: #1073cc !important;
|
|
||||||
background: transparent !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
font-size: 13px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-tabs {
|
|
||||||
display: flex !important;
|
|
||||||
flex-wrap: nowrap !important;
|
|
||||||
gap: 8px !important;
|
|
||||||
overflow-x: auto !important;
|
|
||||||
scrollbar-width: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-tabs::-webkit-scrollbar {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-tabs button {
|
|
||||||
flex: 0 0 auto !important;
|
|
||||||
min-height: 40px !important;
|
|
||||||
padding: 0 14px !important;
|
|
||||||
border: 0 !important;
|
|
||||||
border-radius: 10px !important;
|
|
||||||
color: #687885 !important;
|
|
||||||
background: #f2f5f8 !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
font-size: 14px !important;
|
|
||||||
text-align: center !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-tabs button.is-active {
|
|
||||||
color: #10202c !important;
|
|
||||||
background: #e8edf3 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-empty {
|
|
||||||
display: grid !important;
|
|
||||||
min-height: 170px !important;
|
|
||||||
place-items: center !important;
|
|
||||||
align-content: center !important;
|
|
||||||
gap: 8px !important;
|
|
||||||
color: #8b99a4 !important;
|
|
||||||
text-align: center !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-empty .anticon {
|
|
||||||
color: rgba(30, 189, 219, 0.58) !important;
|
|
||||||
font-size: 42px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-empty strong {
|
|
||||||
color: #7d8a94 !important;
|
|
||||||
font-size: 15px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-empty span {
|
|
||||||
color: #a1adb6 !important;
|
|
||||||
font-size: 12px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-list {
|
|
||||||
display: grid !important;
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
|
|
||||||
gap: 10px !important;
|
|
||||||
min-width: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-list button,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode > button {
|
|
||||||
display: grid !important;
|
|
||||||
align-content: center !important;
|
|
||||||
gap: 5px !important;
|
|
||||||
min-height: 72px !important;
|
|
||||||
border-color: rgba(16, 32, 44, 0.08) !important;
|
|
||||||
border-radius: 16px !important;
|
|
||||||
color: #10202c !important;
|
|
||||||
background: linear-gradient(180deg, #ffffff, #f7fbfc) !important;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.86) !important;
|
|
||||||
white-space: normal !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-list button:hover,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-list button.is-active,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode > button:hover,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode > button.is-active {
|
|
||||||
border-color: rgba(30, 189, 219, 0.34) !important;
|
|
||||||
background: linear-gradient(180deg, #fafdff, #eefbfe) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-list button strong,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode > button strong {
|
|
||||||
min-width: 0 !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
color: #10202c !important;
|
|
||||||
font-size: 14px !important;
|
|
||||||
text-overflow: ellipsis !important;
|
|
||||||
white-space: nowrap !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-list button span,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode > button span,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--work-mode header span,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ai-write header span {
|
|
||||||
color: #7a8c98 !important;
|
|
||||||
font-size: 12px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ai-write textarea {
|
|
||||||
min-height: 136px !important;
|
|
||||||
width: 100% !important;
|
|
||||||
padding: 14px !important;
|
|
||||||
border: 1px solid rgba(16, 32, 44, 0.08) !important;
|
|
||||||
border-radius: 16px !important;
|
|
||||||
color: #10202c !important;
|
|
||||||
background: #fbfdfe !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
font-size: 14px !important;
|
|
||||||
line-height: 1.6 !important;
|
|
||||||
resize: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-ai-submit {
|
|
||||||
min-height: 44px !important;
|
|
||||||
justify-content: center !important;
|
|
||||||
border: 0 !important;
|
|
||||||
border-radius: 14px !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
background: linear-gradient(135deg, #1ebddb 0%, #0f829b 100%) !important;
|
|
||||||
box-shadow: 0 12px 28px rgba(15, 130, 155, 0.22) !important;
|
|
||||||
text-align: center !important;
|
|
||||||
transition: transform 160ms ease, box-shadow 160ms ease !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-ai-submit:hover {
|
|
||||||
background: linear-gradient(135deg, #21c8e3 0%, #1194ad 100%) !important;
|
|
||||||
box-shadow: 0 14px 32px rgba(15, 130, 155, 0.28) !important;
|
|
||||||
transform: translateY(-1px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-toolbar {
|
|
||||||
flex-direction: row !important;
|
|
||||||
align-items: center !important;
|
|
||||||
min-height: 56px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-actions {
|
|
||||||
flex: 1 1 auto !important;
|
|
||||||
max-width: calc(100% - 54px) !important;
|
|
||||||
gap: 7px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool {
|
|
||||||
height: 38px !important;
|
|
||||||
min-height: 38px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--icon {
|
|
||||||
width: 38px !important;
|
|
||||||
min-width: 38px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--upload {
|
|
||||||
max-width: 112px !important;
|
|
||||||
padding: 0 11px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--upload strong {
|
|
||||||
max-width: 56px !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
text-overflow: ellipsis !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--icon::after {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover--library,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover--work-mode,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover--ai-write {
|
|
||||||
inset: calc(100% + 12px) auto auto 0 !important;
|
|
||||||
left: 0 !important;
|
|
||||||
right: auto !important;
|
|
||||||
width: 100% !important;
|
|
||||||
min-width: 0 !important;
|
|
||||||
max-width: 100% !important;
|
|
||||||
max-height: min(420px, calc(100dvh - 380px)) !important;
|
|
||||||
overflow-x: hidden !important;
|
|
||||||
overflow-y: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-library-list {
|
|
||||||
grid-template-columns: minmax(0, 1fr) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 390px) {
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--upload {
|
|
||||||
min-width: 40px !important;
|
|
||||||
width: 40px !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-tool--upload strong {
|
|
||||||
position: absolute !important;
|
|
||||||
width: 1px !important;
|
|
||||||
height: 1px !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
clip: rect(0 0 0 0) !important;
|
|
||||||
clip-path: inset(50%) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 641px) {
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover.ecom-command-popover--library {
|
|
||||||
width: min(540px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
max-width: min(540px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
min-height: 300px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover.ecom-command-popover--work-mode {
|
|
||||||
width: min(340px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
max-width: min(340px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover.ecom-command-popover--ai-write {
|
|
||||||
width: min(430px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
max-width: min(430px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover.ecom-command-popover--library,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover.ecom-command-popover--work-mode,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover.ecom-command-popover--ai-write {
|
|
||||||
inset: calc(100% + 12px) auto auto 0 !important;
|
|
||||||
left: 0 !important;
|
|
||||||
right: auto !important;
|
|
||||||
width: 100% !important;
|
|
||||||
min-width: 0 !important;
|
|
||||||
max-width: 100% !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-height: 700px) {
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover.ecom-command-popover--library {
|
|
||||||
min-height: 0 !important;
|
|
||||||
max-height: min(300px, calc(100dvh - 330px)) !important;
|
|
||||||
overflow-y: auto !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Final composer rhythm: keep attachments compact and pin the toolbelt to the card bottom. */
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer {
|
|
||||||
display: flex !important;
|
|
||||||
flex-direction: column !important;
|
|
||||||
justify-content: flex-start !important;
|
|
||||||
align-items: stretch !important;
|
|
||||||
gap: clamp(12px, 1.6vw, 18px) !important;
|
|
||||||
min-height: clamp(250px, 31vh, 316px) !important;
|
|
||||||
padding: clamp(18px, 2.05vw, 24px) clamp(18px, 2.3vw, 26px) clamp(16px, 1.9vw, 22px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) {
|
|
||||||
min-height: clamp(286px, 35vh, 340px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-asset-popover,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap:not(.has-generated.is-compact) .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-asset-popover {
|
|
||||||
display: flex !important;
|
|
||||||
flex-wrap: nowrap !important;
|
|
||||||
align-items: center !important;
|
|
||||||
align-self: start !important;
|
|
||||||
gap: 12px !important;
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 100% !important;
|
|
||||||
min-height: 64px !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
padding: 0 2px 2px !important;
|
|
||||||
border: 0 !important;
|
|
||||||
background: transparent !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
overflow-x: auto !important;
|
|
||||||
overflow-y: hidden !important;
|
|
||||||
scrollbar-width: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-popover::-webkit-scrollbar {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-add,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap:not(.has-generated.is-compact) .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-asset-add {
|
|
||||||
flex: 0 0 64px !important;
|
|
||||||
width: 64px !important;
|
|
||||||
height: 64px !important;
|
|
||||||
min-height: 64px !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
border: 0 !important;
|
|
||||||
border-radius: 15px !important;
|
|
||||||
background: rgba(30, 189, 219, 0.1) !important;
|
|
||||||
color: #0b8fb2 !important;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.78) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-add span {
|
|
||||||
font-size: 24px !important;
|
|
||||||
line-height: 1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-add small {
|
|
||||||
margin-top: 4px !important;
|
|
||||||
color: #0f7f9e !important;
|
|
||||||
font-size: 14px !important;
|
|
||||||
font-weight: 600 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-thumb,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap:not(.has-generated.is-compact) .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-asset-thumb {
|
|
||||||
flex: 0 0 64px !important;
|
|
||||||
width: 64px !important;
|
|
||||||
height: 64px !important;
|
|
||||||
min-height: 64px !important;
|
|
||||||
border-radius: 15px !important;
|
|
||||||
box-shadow: 0 12px 28px rgba(16, 115, 204, 0.12) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-option-row--settings {
|
|
||||||
align-self: start !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > textarea {
|
|
||||||
flex: 1 1 auto !important;
|
|
||||||
align-self: stretch !important;
|
|
||||||
width: 100% !important;
|
|
||||||
min-height: 86px !important;
|
|
||||||
height: auto !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
line-height: 1.58 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) > textarea {
|
|
||||||
min-height: 78px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-toolbar {
|
|
||||||
flex: 0 0 auto !important;
|
|
||||||
align-self: end !important;
|
|
||||||
width: 100% !important;
|
|
||||||
margin: auto 0 0 !important;
|
|
||||||
padding-top: clamp(12px, 1.45vw, 16px) !important;
|
|
||||||
border-top: 1px solid rgba(30, 189, 219, 0.12) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-actions {
|
|
||||||
min-width: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer {
|
|
||||||
gap: 12px !important;
|
|
||||||
min-height: 318px !important;
|
|
||||||
padding: 18px 16px 16px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) {
|
|
||||||
min-height: 336px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-asset-popover,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap:not(.has-generated.is-compact) .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-asset-popover {
|
|
||||||
gap: 10px !important;
|
|
||||||
min-height: 58px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-add,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-thumb,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap:not(.has-generated.is-compact) .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-asset-add,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap:not(.has-generated.is-compact) .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-asset-thumb {
|
|
||||||
flex-basis: 58px !important;
|
|
||||||
width: 58px !important;
|
|
||||||
height: 58px !important;
|
|
||||||
min-height: 58px !important;
|
|
||||||
border-radius: 14px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-add span {
|
|
||||||
font-size: 22px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-add small {
|
|
||||||
font-size: 13px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > textarea,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) > textarea {
|
|
||||||
min-height: 96px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-toolbar {
|
|
||||||
min-height: 58px !important;
|
|
||||||
padding-top: 12px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 390px) {
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer {
|
|
||||||
min-height: 306px !important;
|
|
||||||
padding-inline: 14px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) {
|
|
||||||
min-height: 326px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-add,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-asset-thumb,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap:not(.has-generated.is-compact) .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-asset-add,
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap:not(.has-generated.is-compact) .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-asset-thumb {
|
|
||||||
flex-basis: 54px !important;
|
|
||||||
width: 54px !important;
|
|
||||||
height: 54px !important;
|
|
||||||
min-height: 54px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -371,3 +371,14 @@
|
|||||||
border-color: rgba(var(--accent-rgb), 0.42);
|
border-color: rgba(var(--accent-rgb), 0.42);
|
||||||
background: var(--bg-panel);
|
background: var(--bg-panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Product set count stepper: align with local light theme ── */
|
||||||
|
html body #root .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-count-stepper {
|
||||||
|
border-color: var(--border-subtle) !important;
|
||||||
|
background: var(--bg-inset) !important;
|
||||||
|
color: var(--fg-body) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html body #root .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-count-stepper b {
|
||||||
|
color: var(--fg-body) !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
html body .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover.ecom-command-popover {
|
html body .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover.ecom-command-popover {
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
@@ -3461,8 +3461,9 @@ html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[d
|
|||||||
row-gap: 10px !important;
|
row-gap: 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-option-row.ecom-command-option-row--settings {
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-option-row.ecom-command-option-row--settings button {
|
||||||
display: none !important;
|
flex: 1 1 calc(50% - 5px) !important;
|
||||||
|
justify-content: flex-start !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-toolbar {
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-toolbar {
|
||||||
@@ -3471,6 +3472,39 @@ html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[d
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 420px) {
|
@media (max-width: 420px) {
|
||||||
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-option-row.ecom-command-option-row--settings {
|
||||||
|
display: grid !important;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
|
||||||
|
gap: 7px !important;
|
||||||
|
justify-content: stretch !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-option-row.ecom-command-option-row--settings button {
|
||||||
|
display: inline-flex !important;
|
||||||
|
width: auto !important;
|
||||||
|
min-width: 0 !important;
|
||||||
|
max-width: none !important;
|
||||||
|
height: 42px !important;
|
||||||
|
min-height: 42px !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
font-size: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-option-row.ecom-command-option-row--settings button > span:not(.ecom-command-option-icon) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-option-row.ecom-command-option-row--settings .ecom-command-option-icon {
|
||||||
|
display: inline-grid !important;
|
||||||
|
width: 22px !important;
|
||||||
|
height: 22px !important;
|
||||||
|
min-width: 22px !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-toolbar {
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-toolbar {
|
||||||
flex-direction: row !important;
|
flex-direction: row !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
@@ -3525,18 +3559,15 @@ html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[d
|
|||||||
z-index: 160 !important;
|
z-index: 160 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--platforms {
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--platform {
|
||||||
width: fit-content !important;
|
width: min(360px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
||||||
min-width: 0 !important;
|
max-width: min(360px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
||||||
max-width: min(320px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--languages,
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--languages,
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--ratio-picker,
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--ratio-picker {
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--duration {
|
width: min(420px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
||||||
width: fit-content !important;
|
max-width: min(420px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
||||||
min-width: 0 !important;
|
|
||||||
max-width: min(320px, calc(100% - var(--composer-popover-left, 0px))) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--settings {
|
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--settings {
|
||||||
|
|||||||
Reference in New Issue
Block a user