dsh-image-gen 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +172 -172
- package/README.md +182 -182
- package/README.zh-CN.md +172 -172
- package/lib/client.js +323 -62
- package/lib/client.js.map +1 -1
- package/lib/index.js +486 -307
- package/lib/types/client/studio-style.d.ts +1 -1
- package/lib/types/image-route.d.ts +18 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/shared.d.ts +17 -4
- package/lib/types/studio.d.ts +1 -0
- package/lib/types/workspace-save.d.ts +7 -0
- package/package.json +10 -8
- package/skills/install-dsh-image-gen/SKILL.md +22 -22
package/lib/client.js
CHANGED
|
@@ -13,6 +13,8 @@ window.__ModuleLoader__.load({
|
|
|
13
13
|
const DELETE_ROUTE = "/plugins/dsh-image-gen/delete";
|
|
14
14
|
/** Same-origin route used by the browser image workbench. */
|
|
15
15
|
const STUDIO_ROUTE = "/plugins/dsh-image-gen/studio";
|
|
16
|
+
/** Browser route used for saving generated images to workspace on demand. */
|
|
17
|
+
const SAVE_WORKSPACE_ROUTE = "/plugins/dsh-image-gen/save-workspace";
|
|
16
18
|
/** Namespace persisted through DSH Settings. */
|
|
17
19
|
const IMAGE_GENERATION_NAMESPACE = "image-generation";
|
|
18
20
|
/** Providers supported by the first browser workbench release. */
|
|
@@ -511,6 +513,26 @@ window.__ModuleLoader__.load({
|
|
|
511
513
|
* This source code is licensed under the ISC license.
|
|
512
514
|
* See the LICENSE file in the root directory of this source tree.
|
|
513
515
|
*/
|
|
516
|
+
const BookmarkPlus = createLucideIcon("bookmark-plus", [
|
|
517
|
+
["path", {
|
|
518
|
+
d: "M12 7v6",
|
|
519
|
+
key: "lw1j43"
|
|
520
|
+
}],
|
|
521
|
+
["path", {
|
|
522
|
+
d: "M15 10H9",
|
|
523
|
+
key: "o6yqo3"
|
|
524
|
+
}],
|
|
525
|
+
["path", {
|
|
526
|
+
d: "M17 3a2 2 0 0 1 2 2v15a1 1 0 0 1-1.496.868l-4.512-2.578a2 2 0 0 0-1.984 0l-4.512 2.578A1 1 0 0 1 5 20V5a2 2 0 0 1 2-2z",
|
|
527
|
+
key: "oz39mx"
|
|
528
|
+
}]
|
|
529
|
+
]);
|
|
530
|
+
/**
|
|
531
|
+
* @license lucide-react v1.38.0 - ISC
|
|
532
|
+
*
|
|
533
|
+
* This source code is licensed under the ISC license.
|
|
534
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
535
|
+
*/
|
|
514
536
|
const Check = createLucideIcon("check", [["path", {
|
|
515
537
|
d: "M20 6 9 17l-5-5",
|
|
516
538
|
key: "1gmf2c"
|
|
@@ -1222,17 +1244,17 @@ window.__ModuleLoader__.load({
|
|
|
1222
1244
|
//#region lib/types/client/studio-view.js
|
|
1223
1245
|
const COPY = {
|
|
1224
1246
|
zh: {
|
|
1225
|
-
title: "
|
|
1247
|
+
title: "云端生图工作台",
|
|
1226
1248
|
configured: "API 已配置",
|
|
1227
1249
|
unconfigured: "未配置",
|
|
1228
1250
|
recent: "最近生成",
|
|
1229
|
-
empty: "
|
|
1251
|
+
empty: "暂无生成历史",
|
|
1230
1252
|
generate: "文生图",
|
|
1231
1253
|
edit: "图生图",
|
|
1232
1254
|
details: "图片详情",
|
|
1233
1255
|
reference: "参考图",
|
|
1234
|
-
optional: "
|
|
1235
|
-
upload: "
|
|
1256
|
+
optional: "选填",
|
|
1257
|
+
upload: "点击或拖拽图片到此处",
|
|
1236
1258
|
uploadHint: "支持 JPG / PNG / WebP / GIF,最大 10MB(最多 5 张)",
|
|
1237
1259
|
prompt: "提示词 Prompt",
|
|
1238
1260
|
clear: "清空",
|
|
@@ -1244,6 +1266,14 @@ window.__ModuleLoader__.load({
|
|
|
1244
1266
|
start: "开始生成",
|
|
1245
1267
|
generating: "正在生成…",
|
|
1246
1268
|
cancelGenerate: "取消生成",
|
|
1269
|
+
count: "生成数量",
|
|
1270
|
+
countUnit: "{n} 张",
|
|
1271
|
+
partialSuccess: "已生成 {success} 张图片,{failed} 张失败",
|
|
1272
|
+
generatingCount: "正在生成(共 {count} 张)…",
|
|
1273
|
+
batchResult: "本次生成(共 {count} 张)",
|
|
1274
|
+
saveToGallery: "收藏进画廊",
|
|
1275
|
+
savedToGallery: "已收藏进画廊",
|
|
1276
|
+
inGallery: "已在画廊",
|
|
1247
1277
|
retry: "重新加载",
|
|
1248
1278
|
configLoadFailed: "工作台配置加载失败,请检查服务后重试。",
|
|
1249
1279
|
noProvider: "请先在设置中配置至少一个云端图像 Provider 的 API Key。",
|
|
@@ -1319,6 +1349,14 @@ window.__ModuleLoader__.load({
|
|
|
1319
1349
|
start: "Generate",
|
|
1320
1350
|
generating: "Generating…",
|
|
1321
1351
|
cancelGenerate: "Cancel",
|
|
1352
|
+
count: "Number of images",
|
|
1353
|
+
countUnit: "{n}",
|
|
1354
|
+
partialSuccess: "Generated {success} images, {failed} failed",
|
|
1355
|
+
generatingCount: "Generating ({count} images)…",
|
|
1356
|
+
batchResult: "Generated {count} images",
|
|
1357
|
+
saveToGallery: "Save to Gallery",
|
|
1358
|
+
savedToGallery: "Saved to Gallery",
|
|
1359
|
+
inGallery: "In Gallery",
|
|
1322
1360
|
retry: "Retry",
|
|
1323
1361
|
configLoadFailed: "Failed to load studio configuration.",
|
|
1324
1362
|
noProvider: "Configure an API key for at least one cloud image provider in Settings.",
|
|
@@ -1389,6 +1427,8 @@ window.__ModuleLoader__.load({
|
|
|
1389
1427
|
const [quality, setQuality] = (0, react.useState)("1K");
|
|
1390
1428
|
const [prompt, setPrompt] = (0, react.useState)("");
|
|
1391
1429
|
const [references, setReferences] = (0, react.useState)([]);
|
|
1430
|
+
const [count, setCount] = (0, react.useState)(1);
|
|
1431
|
+
const [currentBatch, setCurrentBatch] = (0, react.useState)(null);
|
|
1392
1432
|
const [isGenerating, setIsGenerating] = (0, react.useState)(false);
|
|
1393
1433
|
const [error, setError] = (0, react.useState)(null);
|
|
1394
1434
|
const [notice, setNotice] = (0, react.useState)(null);
|
|
@@ -1476,7 +1516,7 @@ window.__ModuleLoader__.load({
|
|
|
1476
1516
|
const canvasEl = canvasRef.current;
|
|
1477
1517
|
if (!canvasEl) return;
|
|
1478
1518
|
const onWheel = (e) => {
|
|
1479
|
-
if (selected === null ||
|
|
1519
|
+
if (selected === null && (!currentBatch || currentBatch.length === 0)) return;
|
|
1480
1520
|
e.preventDefault();
|
|
1481
1521
|
const delta = e.deltaY < 0 ? 15 : -15;
|
|
1482
1522
|
setFit(false);
|
|
@@ -1484,7 +1524,7 @@ window.__ModuleLoader__.load({
|
|
|
1484
1524
|
};
|
|
1485
1525
|
canvasEl.addEventListener("wheel", onWheel, { passive: false });
|
|
1486
1526
|
return () => canvasEl.removeEventListener("wheel", onWheel);
|
|
1487
|
-
}, [selected,
|
|
1527
|
+
}, [selected, currentBatch]);
|
|
1488
1528
|
(0, react.useEffect)(() => {
|
|
1489
1529
|
const handleMouseMove = (e) => {
|
|
1490
1530
|
if (!dragStartRef.current) return;
|
|
@@ -1544,18 +1584,20 @@ window.__ModuleLoader__.load({
|
|
|
1544
1584
|
});
|
|
1545
1585
|
};
|
|
1546
1586
|
const selectItem = (item) => {
|
|
1587
|
+
setCurrentBatch(null);
|
|
1547
1588
|
setSelected(item);
|
|
1548
1589
|
setPanelTab("details");
|
|
1549
1590
|
resetFit();
|
|
1550
1591
|
};
|
|
1551
1592
|
const startNew = () => {
|
|
1593
|
+
setCurrentBatch(null);
|
|
1552
1594
|
setSelected(null);
|
|
1553
1595
|
setPanelTab("generate");
|
|
1554
1596
|
resetFit();
|
|
1555
1597
|
};
|
|
1556
1598
|
const handleCanvasMouseDown = (e) => {
|
|
1557
1599
|
if (e.button !== 0 && e.button !== 1) return;
|
|
1558
|
-
if (selected === null ||
|
|
1600
|
+
if (selected === null && (!currentBatch || currentBatch.length === 0)) return;
|
|
1559
1601
|
setIsDragging(true);
|
|
1560
1602
|
hasDraggedRef.current = false;
|
|
1561
1603
|
dragStartRef.current = {
|
|
@@ -1565,9 +1607,7 @@ window.__ModuleLoader__.load({
|
|
|
1565
1607
|
startY: offset.y
|
|
1566
1608
|
};
|
|
1567
1609
|
};
|
|
1568
|
-
const handleImageClick = () => {
|
|
1569
|
-
if (!hasDraggedRef.current) setLightboxOpen(true);
|
|
1570
|
-
};
|
|
1610
|
+
const handleImageClick = () => {};
|
|
1571
1611
|
const addReferenceFiles = (fileList) => {
|
|
1572
1612
|
if (!fileList || fileList.length === 0) return;
|
|
1573
1613
|
const files = Array.from(fileList);
|
|
@@ -1692,30 +1732,45 @@ window.__ModuleLoader__.load({
|
|
|
1692
1732
|
prompt: prompt.trim(),
|
|
1693
1733
|
ratio,
|
|
1694
1734
|
quality,
|
|
1735
|
+
...count > 1 ? { count } : {},
|
|
1695
1736
|
...workspace?.path ? { workspaceRoot: workspace.path } : {},
|
|
1696
1737
|
...referencesPayload === void 0 ? {} : { references: referencesPayload }
|
|
1697
1738
|
})
|
|
1698
1739
|
});
|
|
1699
1740
|
const payload = await response.json();
|
|
1700
1741
|
if (!response.ok || !("attachment" in payload)) throw new Error("error" in payload && payload.error ? payload.error : t("generationFailed"));
|
|
1701
|
-
const
|
|
1702
|
-
id: String(payload.attachment.attachmentId),
|
|
1742
|
+
const generatedList = Array.isArray(payload.items) && payload.items.length > 0 ? payload.items : [{
|
|
1703
1743
|
attachment: payload.attachment,
|
|
1744
|
+
output: payload.output,
|
|
1745
|
+
...payload.savedTo ? { savedTo: payload.savedTo } : {}
|
|
1746
|
+
}];
|
|
1747
|
+
const galleryEntries = generatedList.map((gen, idx) => ({
|
|
1748
|
+
id: String(gen.attachment.attachmentId || `${payload.createdAt}-${idx}`),
|
|
1749
|
+
attachment: gen.attachment,
|
|
1704
1750
|
prompt: payload.prompt,
|
|
1705
1751
|
provider: payload.provider,
|
|
1706
1752
|
model: payload.model,
|
|
1707
|
-
createdAt: payload.createdAt,
|
|
1753
|
+
createdAt: payload.createdAt + idx,
|
|
1708
1754
|
aspectRatio: ratio,
|
|
1709
1755
|
imageSize: quality,
|
|
1710
|
-
output:
|
|
1711
|
-
...
|
|
1756
|
+
output: gen.output,
|
|
1757
|
+
...gen.savedTo ? { savedTo: gen.savedTo } : {},
|
|
1712
1758
|
...workspace?.path ? { workspacePath: workspace.path } : {},
|
|
1713
1759
|
...workspace?.workspaceId ? { workspaceId: workspace.workspaceId } : {}
|
|
1714
|
-
};
|
|
1715
|
-
|
|
1716
|
-
|
|
1760
|
+
}));
|
|
1761
|
+
if (galleryEntries.length > 1) {
|
|
1762
|
+
setCurrentBatch(galleryEntries);
|
|
1763
|
+
setSelected(galleryEntries[0]);
|
|
1764
|
+
} else if (galleryEntries.length === 1) {
|
|
1765
|
+
setCurrentBatch(null);
|
|
1766
|
+
setSelected(galleryEntries[0]);
|
|
1767
|
+
}
|
|
1717
1768
|
setPanelTab("details");
|
|
1718
1769
|
resetFit();
|
|
1770
|
+
if (payload.failedCount && payload.failedCount > 0) flash(t("partialSuccess", {
|
|
1771
|
+
success: String(generatedList.length),
|
|
1772
|
+
failed: String(payload.failedCount)
|
|
1773
|
+
}));
|
|
1719
1774
|
} catch (submitError) {
|
|
1720
1775
|
if (controller.signal.aborted) return;
|
|
1721
1776
|
setError(messageOf(submitError));
|
|
@@ -1726,6 +1781,42 @@ window.__ModuleLoader__.load({
|
|
|
1726
1781
|
}
|
|
1727
1782
|
}
|
|
1728
1783
|
};
|
|
1784
|
+
const isSelectedInGallery = (0, react.useMemo)(() => {
|
|
1785
|
+
if (selected === null) return false;
|
|
1786
|
+
return items.some((item) => item.id === selected.id);
|
|
1787
|
+
}, [items, selected]);
|
|
1788
|
+
const handleSaveToGallery = async () => {
|
|
1789
|
+
if (selected === null || isSelectedInGallery) return;
|
|
1790
|
+
let savedTo = selected.savedTo;
|
|
1791
|
+
const targetRoot = workspace?.path || config?.workspaceRoot;
|
|
1792
|
+
if (!savedTo) try {
|
|
1793
|
+
const res = await fetch(SAVE_WORKSPACE_ROUTE, {
|
|
1794
|
+
method: "POST",
|
|
1795
|
+
credentials: "same-origin",
|
|
1796
|
+
headers: { "content-type": "application/json" },
|
|
1797
|
+
body: JSON.stringify({
|
|
1798
|
+
attachment: selected.attachment,
|
|
1799
|
+
...targetRoot ? { workspaceRoot: targetRoot } : {}
|
|
1800
|
+
})
|
|
1801
|
+
});
|
|
1802
|
+
if (res.ok) {
|
|
1803
|
+
const data = await res.json();
|
|
1804
|
+
if (data.savedTo) savedTo = data.savedTo;
|
|
1805
|
+
}
|
|
1806
|
+
} catch (e) {
|
|
1807
|
+
console.warn("Failed to save to workspace:", e);
|
|
1808
|
+
}
|
|
1809
|
+
const updatedItem = {
|
|
1810
|
+
...selected,
|
|
1811
|
+
...savedTo ? { savedTo } : {},
|
|
1812
|
+
...targetRoot ? { workspacePath: targetRoot } : {},
|
|
1813
|
+
...workspace?.workspaceId ? { workspaceId: workspace.workspaceId } : {}
|
|
1814
|
+
};
|
|
1815
|
+
await saveGalleryItem(updatedItem);
|
|
1816
|
+
setSelected(updatedItem);
|
|
1817
|
+
if (currentBatch) setCurrentBatch((prev) => prev ? prev.map((i) => i.id === updatedItem.id ? updatedItem : i) : prev);
|
|
1818
|
+
flash(t("savedToGallery"));
|
|
1819
|
+
};
|
|
1729
1820
|
const handleConfirmDelete = async () => {
|
|
1730
1821
|
if (selected === null) return;
|
|
1731
1822
|
const idToDelete = selected.id;
|
|
@@ -1747,8 +1838,21 @@ window.__ModuleLoader__.load({
|
|
|
1747
1838
|
throw new Error(reason);
|
|
1748
1839
|
}
|
|
1749
1840
|
}
|
|
1750
|
-
await deleteGalleryItem(idToDelete);
|
|
1841
|
+
if (isSelectedInGallery) await deleteGalleryItem(idToDelete);
|
|
1751
1842
|
evictAttachmentCache(attachmentId);
|
|
1843
|
+
if (currentBatch) {
|
|
1844
|
+
const remaining = currentBatch.filter((i) => i.id !== idToDelete);
|
|
1845
|
+
if (remaining.length > 1) {
|
|
1846
|
+
setCurrentBatch(remaining);
|
|
1847
|
+
setSelected(remaining[0]);
|
|
1848
|
+
} else if (remaining.length === 1) {
|
|
1849
|
+
setCurrentBatch(null);
|
|
1850
|
+
setSelected(remaining[0]);
|
|
1851
|
+
} else {
|
|
1852
|
+
setCurrentBatch(null);
|
|
1853
|
+
setSelected(null);
|
|
1854
|
+
}
|
|
1855
|
+
} else setSelected(null);
|
|
1752
1856
|
flash(t("deletedToast"));
|
|
1753
1857
|
} catch (delError) {
|
|
1754
1858
|
setError(messageOf(delError));
|
|
@@ -1766,13 +1870,50 @@ window.__ModuleLoader__.load({
|
|
|
1766
1870
|
const toggleFavorite = async () => {
|
|
1767
1871
|
if (selected === null) return;
|
|
1768
1872
|
const targetId = selected.id;
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1873
|
+
if (isSelectedInGallery) {
|
|
1874
|
+
const nextFav = await toggleFavoriteGalleryItem(targetId);
|
|
1875
|
+
setSelected((curr) => curr !== null && curr.id === targetId ? {
|
|
1876
|
+
...curr,
|
|
1877
|
+
isFavorite: nextFav
|
|
1878
|
+
} : curr);
|
|
1879
|
+
if (currentBatch) setCurrentBatch((prev) => prev ? prev.map((i) => i.id === targetId ? {
|
|
1880
|
+
...i,
|
|
1881
|
+
isFavorite: nextFav
|
|
1882
|
+
} : i) : null);
|
|
1883
|
+
flash(nextFav ? t("favoriteAdded") : t("favoriteRemoved"));
|
|
1884
|
+
} else {
|
|
1885
|
+
const nextFav = !selected.isFavorite;
|
|
1886
|
+
setSelected((curr) => curr !== null && curr.id === targetId ? {
|
|
1887
|
+
...curr,
|
|
1888
|
+
isFavorite: nextFav
|
|
1889
|
+
} : curr);
|
|
1890
|
+
if (currentBatch) setCurrentBatch((prev) => prev ? prev.map((i) => i.id === targetId ? {
|
|
1891
|
+
...i,
|
|
1892
|
+
isFavorite: nextFav
|
|
1893
|
+
} : i) : null);
|
|
1894
|
+
flash(nextFav ? t("favoriteAdded") : t("favoriteRemoved"));
|
|
1895
|
+
}
|
|
1896
|
+
};
|
|
1897
|
+
const stepLightbox = (delta) => {
|
|
1898
|
+
if (!currentBatch || currentBatch.length <= 1 || selected === null) return;
|
|
1899
|
+
const currIdx = currentBatch.findIndex((i) => i.id === selected.id);
|
|
1900
|
+
if (currIdx === -1) return;
|
|
1901
|
+
const nextIdx = (currIdx + delta + currentBatch.length) % currentBatch.length;
|
|
1902
|
+
setSelected(currentBatch[nextIdx]);
|
|
1775
1903
|
};
|
|
1904
|
+
(0, react.useEffect)(() => {
|
|
1905
|
+
if (!lightboxOpen || !currentBatch || currentBatch.length <= 1) return;
|
|
1906
|
+
const onKeyDown = (e) => {
|
|
1907
|
+
if (e.key === "ArrowLeft") stepLightbox(-1);
|
|
1908
|
+
else if (e.key === "ArrowRight") stepLightbox(1);
|
|
1909
|
+
};
|
|
1910
|
+
window.addEventListener("keydown", onKeyDown);
|
|
1911
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
1912
|
+
}, [
|
|
1913
|
+
lightboxOpen,
|
|
1914
|
+
currentBatch,
|
|
1915
|
+
selected
|
|
1916
|
+
]);
|
|
1776
1917
|
const flash = (message) => {
|
|
1777
1918
|
setNotice(message);
|
|
1778
1919
|
window.setTimeout(() => setNotice(null), 2200);
|
|
@@ -1933,13 +2074,29 @@ window.__ModuleLoader__.load({
|
|
|
1933
2074
|
className: "dsh-ig-generation-orbit",
|
|
1934
2075
|
children: (0, react_jsx_runtime.jsx)(Sparkles, { size: 28 })
|
|
1935
2076
|
}),
|
|
1936
|
-
(0, react_jsx_runtime.jsx)("strong", { children: t("generating") }),
|
|
2077
|
+
(0, react_jsx_runtime.jsx)("strong", { children: count > 1 ? t("generatingCount", { count: String(count) }) : t("generating") }),
|
|
1937
2078
|
(0, react_jsx_runtime.jsxs)("span", { children: [
|
|
1938
2079
|
activeProfile?.label,
|
|
1939
2080
|
" · ",
|
|
1940
2081
|
model
|
|
1941
2082
|
] })
|
|
1942
2083
|
]
|
|
2084
|
+
}) : currentBatch && currentBatch.length > 1 ? (0, react_jsx_runtime.jsx)("div", {
|
|
2085
|
+
className: "dsh-ig-canvas-cluster",
|
|
2086
|
+
"data-count": currentBatch.length,
|
|
2087
|
+
style: {
|
|
2088
|
+
transform: `translate(${offset.x}px, ${offset.y}px) scale(${zoom / 100})`,
|
|
2089
|
+
transformOrigin: "center center",
|
|
2090
|
+
transition: isDragging ? "none" : "transform 0.08s ease-out"
|
|
2091
|
+
},
|
|
2092
|
+
children: currentBatch.map((batchItem, index) => (0, react_jsx_runtime.jsx)(BatchCanvasItem, {
|
|
2093
|
+
item: batchItem,
|
|
2094
|
+
index,
|
|
2095
|
+
isSelected: selected?.id === batchItem.id,
|
|
2096
|
+
onSelect: () => {
|
|
2097
|
+
if (!hasDraggedRef.current) setSelected(batchItem);
|
|
2098
|
+
}
|
|
2099
|
+
}, batchItem.id))
|
|
1943
2100
|
}) : selected === null ? (0, react_jsx_runtime.jsxs)("div", {
|
|
1944
2101
|
className: "dsh-ig-canvas-empty",
|
|
1945
2102
|
children: [(0, react_jsx_runtime.jsx)(ImagePlus, { size: 36 }), (0, react_jsx_runtime.jsx)("span", { children: t("selectHistory") })]
|
|
@@ -1984,6 +2141,14 @@ window.__ModuleLoader__.load({
|
|
|
1984
2141
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
1985
2142
|
className: "dsh-ig-result-actions",
|
|
1986
2143
|
children: [(0, react_jsx_runtime.jsx)("p", { children: selected.prompt }), (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
2144
|
+
(0, react_jsx_runtime.jsxs)("button", {
|
|
2145
|
+
type: "button",
|
|
2146
|
+
className: `dsh-ig-save-gallery-btn ${isSelectedInGallery ? "is-saved" : ""}`,
|
|
2147
|
+
onClick: () => void handleSaveToGallery(),
|
|
2148
|
+
title: isSelectedInGallery ? t("inGallery") : t("saveToGallery"),
|
|
2149
|
+
disabled: isSelectedInGallery,
|
|
2150
|
+
children: [isSelectedInGallery ? (0, react_jsx_runtime.jsx)(Check, { size: 15 }) : (0, react_jsx_runtime.jsx)(BookmarkPlus, { size: 15 }), (0, react_jsx_runtime.jsx)("span", { children: isSelectedInGallery ? t("inGallery") : t("saveToGallery") })]
|
|
2151
|
+
}),
|
|
1987
2152
|
(0, react_jsx_runtime.jsxs)("button", {
|
|
1988
2153
|
type: "button",
|
|
1989
2154
|
onClick: () => void toggleFavorite(),
|
|
@@ -2177,39 +2342,59 @@ window.__ModuleLoader__.load({
|
|
|
2177
2342
|
onClick: () => void loadConfig(),
|
|
2178
2343
|
children: [(0, react_jsx_runtime.jsx)(RefreshCw, { size: 13 }), (0, react_jsx_runtime.jsx)("span", { children: t("retry") })]
|
|
2179
2344
|
})]
|
|
2180
|
-
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2345
|
+
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2346
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
2347
|
+
className: "dsh-ig-field-grid",
|
|
2348
|
+
children: [(0, react_jsx_runtime.jsx)(FieldSelect, {
|
|
2349
|
+
label: t("provider"),
|
|
2350
|
+
value: provider,
|
|
2351
|
+
onChange: changeProvider,
|
|
2352
|
+
options: config.providers.map((item) => ({
|
|
2353
|
+
value: item.provider,
|
|
2354
|
+
label: `${item.label}${item.configured ? "" : ` · ${t("unconfigured")}`}`
|
|
2355
|
+
}))
|
|
2356
|
+
}), (0, react_jsx_runtime.jsx)(FieldSelect, {
|
|
2357
|
+
label: t("model"),
|
|
2358
|
+
value: model,
|
|
2359
|
+
onChange: setModel,
|
|
2360
|
+
options: activeProfile === void 0 ? [] : [{
|
|
2361
|
+
value: activeProfile.model,
|
|
2362
|
+
label: activeProfile.model
|
|
2363
|
+
}]
|
|
2364
|
+
})]
|
|
2365
|
+
}),
|
|
2366
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
2367
|
+
className: "dsh-ig-field-grid",
|
|
2368
|
+
children: [(0, react_jsx_runtime.jsx)(FieldSelect, {
|
|
2369
|
+
label: t("ratio"),
|
|
2370
|
+
value: ratio,
|
|
2371
|
+
onChange: setRatio,
|
|
2372
|
+
options: activeProfile?.ratioOptions ?? []
|
|
2373
|
+
}), (0, react_jsx_runtime.jsx)(FieldSelect, {
|
|
2374
|
+
label: t("quality"),
|
|
2375
|
+
value: quality,
|
|
2376
|
+
onChange: setQuality,
|
|
2377
|
+
options: activeProfile?.qualityOptions ?? []
|
|
2378
|
+
})]
|
|
2379
|
+
}),
|
|
2380
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
2381
|
+
className: "dsh-ig-field",
|
|
2382
|
+
children: [(0, react_jsx_runtime.jsx)("label", { children: t("count") }), (0, react_jsx_runtime.jsx)("div", {
|
|
2383
|
+
className: "dsh-ig-count-row",
|
|
2384
|
+
children: [
|
|
2385
|
+
1,
|
|
2386
|
+
2,
|
|
2387
|
+
3,
|
|
2388
|
+
4
|
|
2389
|
+
].map((option) => (0, react_jsx_runtime.jsx)("button", {
|
|
2390
|
+
type: "button",
|
|
2391
|
+
className: `dsh-ig-count-pill ${count === option ? "is-active" : ""}`,
|
|
2392
|
+
onClick: () => setCount(option),
|
|
2393
|
+
children: t("countUnit", { n: String(option) })
|
|
2394
|
+
}, option))
|
|
2395
|
+
})]
|
|
2396
|
+
})
|
|
2397
|
+
] }),
|
|
2213
2398
|
configuredCount === 0 && config !== null && (0, react_jsx_runtime.jsx)("div", {
|
|
2214
2399
|
className: "dsh-ig-inline-note",
|
|
2215
2400
|
children: t("noProvider")
|
|
@@ -2231,7 +2416,7 @@ window.__ModuleLoader__.load({
|
|
|
2231
2416
|
className: "dsh-ig-generate-button",
|
|
2232
2417
|
disabled: config === null,
|
|
2233
2418
|
onClick: () => void submit(),
|
|
2234
|
-
children: [(0, react_jsx_runtime.jsx)(Sparkles, { size: 17 }), (0, react_jsx_runtime.
|
|
2419
|
+
children: [(0, react_jsx_runtime.jsx)(Sparkles, { size: 17 }), (0, react_jsx_runtime.jsxs)("span", { children: [t("start"), count > 1 ? ` (${count})` : ""] })]
|
|
2235
2420
|
})
|
|
2236
2421
|
]
|
|
2237
2422
|
})]
|
|
@@ -2255,6 +2440,14 @@ window.__ModuleLoader__.load({
|
|
|
2255
2440
|
className: "dsh-ig-tag dsh-ig-tag-model",
|
|
2256
2441
|
children: selected.model
|
|
2257
2442
|
}),
|
|
2443
|
+
currentBatch && currentBatch.length > 1 && (0, react_jsx_runtime.jsxs)("span", {
|
|
2444
|
+
className: "dsh-ig-tag",
|
|
2445
|
+
children: [
|
|
2446
|
+
currentBatch.findIndex((i) => i.id === selected.id) + 1,
|
|
2447
|
+
" / ",
|
|
2448
|
+
currentBatch.length
|
|
2449
|
+
]
|
|
2450
|
+
}),
|
|
2258
2451
|
selected.attachment.width && selected.attachment.height ? (0, react_jsx_runtime.jsxs)("span", {
|
|
2259
2452
|
className: "dsh-ig-tag",
|
|
2260
2453
|
children: [
|
|
@@ -2272,6 +2465,25 @@ window.__ModuleLoader__.load({
|
|
|
2272
2465
|
children: (0, react_jsx_runtime.jsx)(X, { size: 18 })
|
|
2273
2466
|
})]
|
|
2274
2467
|
}),
|
|
2468
|
+
currentBatch && currentBatch.length > 1 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("button", {
|
|
2469
|
+
type: "button",
|
|
2470
|
+
className: "dsh-ig-lightbox-nav is-prev",
|
|
2471
|
+
onClick: (e) => {
|
|
2472
|
+
e.stopPropagation();
|
|
2473
|
+
stepLightbox(-1);
|
|
2474
|
+
},
|
|
2475
|
+
title: "上一张",
|
|
2476
|
+
children: (0, react_jsx_runtime.jsx)(ChevronLeft, { size: 24 })
|
|
2477
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
2478
|
+
type: "button",
|
|
2479
|
+
className: "dsh-ig-lightbox-nav is-next",
|
|
2480
|
+
onClick: (e) => {
|
|
2481
|
+
e.stopPropagation();
|
|
2482
|
+
stepLightbox(1);
|
|
2483
|
+
},
|
|
2484
|
+
title: "下一张",
|
|
2485
|
+
children: (0, react_jsx_runtime.jsx)(ChevronRight, { size: 24 })
|
|
2486
|
+
})] }),
|
|
2275
2487
|
(0, react_jsx_runtime.jsx)("div", {
|
|
2276
2488
|
className: "dsh-ig-lightbox-img-wrap",
|
|
2277
2489
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -2322,6 +2534,14 @@ window.__ModuleLoader__.load({
|
|
|
2322
2534
|
onClick: downloadSelected,
|
|
2323
2535
|
children: [(0, react_jsx_runtime.jsx)(Download, { size: 14 }), (0, react_jsx_runtime.jsx)("span", { children: t("download") })]
|
|
2324
2536
|
}),
|
|
2537
|
+
(0, react_jsx_runtime.jsxs)("button", {
|
|
2538
|
+
type: "button",
|
|
2539
|
+
className: `dsh-ig-lightbox-btn ${isSelectedInGallery ? "is-saved" : ""}`,
|
|
2540
|
+
title: isSelectedInGallery ? t("inGallery") : t("saveToGallery"),
|
|
2541
|
+
onClick: () => void handleSaveToGallery(),
|
|
2542
|
+
disabled: isSelectedInGallery,
|
|
2543
|
+
children: [isSelectedInGallery ? (0, react_jsx_runtime.jsx)(Check, { size: 14 }) : (0, react_jsx_runtime.jsx)(BookmarkPlus, { size: 14 }), (0, react_jsx_runtime.jsx)("span", { children: isSelectedInGallery ? t("inGallery") : t("saveToGallery") })]
|
|
2544
|
+
}),
|
|
2325
2545
|
(0, react_jsx_runtime.jsxs)("button", {
|
|
2326
2546
|
type: "button",
|
|
2327
2547
|
className: "dsh-ig-lightbox-btn",
|
|
@@ -2388,6 +2608,30 @@ window.__ModuleLoader__.load({
|
|
|
2388
2608
|
]
|
|
2389
2609
|
});
|
|
2390
2610
|
};
|
|
2611
|
+
const BatchCanvasItem = ({ item, index, isSelected, onSelect }) => {
|
|
2612
|
+
const image = useAttachmentImage(item.attachment, true);
|
|
2613
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
2614
|
+
className: `dsh-ig-canvas-item ${isSelected ? "is-selected" : ""}`,
|
|
2615
|
+
onClick: onSelect,
|
|
2616
|
+
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
2617
|
+
className: "dsh-ig-canvas-badge",
|
|
2618
|
+
children: ["#", index + 1]
|
|
2619
|
+
}), image.url !== null ? (0, react_jsx_runtime.jsx)("img", {
|
|
2620
|
+
src: image.url,
|
|
2621
|
+
alt: item.prompt,
|
|
2622
|
+
draggable: false
|
|
2623
|
+
}) : image.loading ? (0, react_jsx_runtime.jsx)("div", {
|
|
2624
|
+
className: "dsh-ig-canvas-item-loading",
|
|
2625
|
+
children: (0, react_jsx_runtime.jsx)(LoaderCircle, {
|
|
2626
|
+
className: "dsh-ig-spin",
|
|
2627
|
+
size: 24
|
|
2628
|
+
})
|
|
2629
|
+
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
2630
|
+
className: "dsh-ig-canvas-item-loading",
|
|
2631
|
+
children: (0, react_jsx_runtime.jsx)(ImagePlus, { size: 24 })
|
|
2632
|
+
})]
|
|
2633
|
+
});
|
|
2634
|
+
};
|
|
2391
2635
|
const FieldSelect = ({ label, value, options, onChange }) => (0, react_jsx_runtime.jsxs)("label", {
|
|
2392
2636
|
className: "dsh-ig-field-select",
|
|
2393
2637
|
children: [(0, react_jsx_runtime.jsx)("span", { children: label }), (0, react_jsx_runtime.jsx)("select", {
|
|
@@ -4103,13 +4347,13 @@ window.__ModuleLoader__.load({
|
|
|
4103
4347
|
.is-configured .dsh-ig-status-item-tag{color:#059669;background:rgba(16,185,129,.14)}
|
|
4104
4348
|
.is-missing .dsh-ig-status-item-tag{color:#dc2626;background:rgba(239,68,68,.14)}
|
|
4105
4349
|
.dsh-ig-canvas{position:relative;flex:1 1 0;height:0;min-height:0;display:flex;align-items:center;justify-content:center;overflow:hidden;padding:24px;touch-action:none;user-select:none;cursor:grab;background-image:linear-gradient(45deg,rgba(114,128,156,.035) 25%,transparent 25%),linear-gradient(-45deg,rgba(114,128,156,.035) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,rgba(114,128,156,.035) 75%),linear-gradient(-45deg,transparent 75%,rgba(114,128,156,.035) 75%);background-size:24px 24px;background-position:0 0,0 12px,12px -12px,-12px 0}
|
|
4106
|
-
.dsh-ig-canvas.is-dragging{cursor:grabbing!important}
|
|
4350
|
+
.dsh-ig-canvas.is-dragging,.dsh-ig-canvas.is-dragging *{cursor:grabbing!important}
|
|
4107
4351
|
.dsh-ig-canvas img{display:block;max-width:100%;max-height:100%;width:auto;height:auto;border-radius:10px;box-shadow:0 14px 45px rgba(25,35,63,.18);user-select:none;-webkit-user-drag:none;pointer-events:auto}
|
|
4108
4352
|
.dsh-ig-canvas-empty,.dsh-ig-generating-state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:12px;color:#929bad;font-size:12px;padding:26px;cursor:default}
|
|
4109
4353
|
.dsh-ig-generating-state strong{font-size:15px;color:var(--foreground,#182033)}.dsh-ig-generating-state span{font-size:11px}.dsh-ig-generation-orbit{width:66px;height:66px;border-radius:50%;display:grid;place-items:center;color:var(--ig-blue);background:rgba(47,100,245,.09);box-shadow:0 0 0 10px rgba(47,100,245,.035);animation:dshIgPulse 1.8s ease-in-out infinite}
|
|
4110
4354
|
.dsh-ig-result-strip{flex:0 0 auto;min-height:52px;padding:8px 14px;display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--ig-line)}.dsh-ig-result-strip>span{font-size:12px;font-weight:650}.dsh-ig-result-strip>div,.dsh-ig-result-actions>div{display:flex;gap:7px}.dsh-ig-result-strip button,.dsh-ig-result-actions button{height:32px;display:inline-flex;align-items:center;gap:6px;padding:0 10px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);font-size:11px;cursor:pointer}.dsh-ig-result-strip button:hover,.dsh-ig-result-actions button:hover{border-color:#9fb2ed;color:var(--ig-blue)}.dsh-ig-result-actions{flex:0 0 auto;min-height:54px;padding:8px 14px;display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--ig-line)}.dsh-ig-result-actions p{margin:0;min-width:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:11.5px;line-height:18px;color:#596277}.dsh-ig-result-meta{flex:0 0 auto;min-height:32px;padding:6px 14px;display:flex;gap:13px;align-items:center;flex-wrap:wrap;border-top:1px solid var(--ig-line);font-size:10px;color:#8790a3}.dsh-ig-result-meta span+span:before{content:'·';margin-right:13px}
|
|
4111
4355
|
.dsh-ig-generate-panel{height:100%;display:flex;flex-direction:column;border-left:1px solid var(--ig-line);overflow:hidden}.dsh-ig-panel-tabs{height:48px;flex:0 0 48px;display:grid;grid-template-columns:1fr 1fr;border-bottom:1px solid var(--ig-line);padding:0 14px}.dsh-ig-panel-tabs button{position:relative;border:0;background:transparent;font-size:12px;color:#7c8598;cursor:pointer}.dsh-ig-panel-tabs button.is-active{color:var(--ig-blue);font-weight:650}.dsh-ig-panel-tabs button.is-active:after{content:'';position:absolute;left:20%;right:20%;bottom:-1px;height:2px;background:var(--ig-blue);border-radius:2px 2px 0 0}.dsh-ig-generator-form{flex:1 1 0;height:0;padding:15px;display:flex;flex-direction:column;gap:15px;overflow-x:hidden;overflow-y:auto;min-height:0}.dsh-ig-mode-switch{display:grid;grid-template-columns:1fr 1fr;gap:8px}.dsh-ig-mode-switch button{height:39px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);display:flex;align-items:center;justify-content:center;gap:7px;font-size:12px;cursor:pointer}.dsh-ig-mode-switch button.is-active{border-color:#789bff;color:var(--ig-blue);background:rgba(47,100,245,.065);box-shadow:inset 0 0 0 1px rgba(47,100,245,.1)}
|
|
4112
|
-
.dsh-ig-field{position:relative;display:flex;flex-direction:column;gap:7px}.dsh-ig-field>label,.dsh-ig-field-label label{font-size:11.5px;font-weight:630}.dsh-ig-field>label span{font-weight:400;color:#929bad}.dsh-ig-field-label{display:flex;align-items:center;justify-content:space-between}.dsh-ig-field-label b{color:#e14d4d}.dsh-ig-field-label button{border:0;background:transparent;color:#798397;font-size:10.5px;cursor:pointer}.dsh-ig-field textarea{width:100%;height:112px;padding:11px 12px 22px;resize:vertical;border:1px solid var(--ig-line);border-radius:9px;background:var(--background,#fff);font-size:12px;line-height:19px;outline:none}.dsh-ig-field textarea:focus{border-color:var(--ig-blue);box-shadow:0 0 0 3px rgba(47,100,245,.09)}.dsh-ig-field>small{position:absolute;right:9px;bottom:7px;color:#9aa2b2;font-size:9.5px}.dsh-ig-field-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px}.dsh-ig-field-select{display:flex;flex-direction:column;gap:6px;min-width:0}.dsh-ig-field-select>span{font-size:11px;font-weight:620}.dsh-ig-field-select select{width:100%;height:36px;padding:0 26px 0 9px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);font-size:11px;outline:none;text-overflow:ellipsis}.dsh-ig-field-select select:focus{border-color:var(--ig-blue)}
|
|
4356
|
+
.dsh-ig-field{position:relative;display:flex;flex-direction:column;gap:7px}.dsh-ig-field>label,.dsh-ig-field-label label{font-size:11.5px;font-weight:630}.dsh-ig-field>label span{font-weight:400;color:#929bad}.dsh-ig-field-label{display:flex;align-items:center;justify-content:space-between}.dsh-ig-field-label b{color:#e14d4d}.dsh-ig-field-label button{border:0;background:transparent;color:#798397;font-size:10.5px;cursor:pointer}.dsh-ig-field textarea{width:100%;height:112px;padding:11px 12px 22px;resize:vertical;border:1px solid var(--ig-line);border-radius:9px;background:var(--background,#fff);font-size:12px;line-height:19px;outline:none}.dsh-ig-field textarea:focus{border-color:var(--ig-blue);box-shadow:0 0 0 3px rgba(47,100,245,.09)}.dsh-ig-field>small{position:absolute;right:9px;bottom:7px;color:#9aa2b2;font-size:9.5px}.dsh-ig-field-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px}.dsh-ig-field-select{display:flex;flex-direction:column;gap:6px;min-width:0}.dsh-ig-field-select>span{font-size:11px;font-weight:620}.dsh-ig-field-select select{width:100%;height:36px;padding:0 26px 0 9px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);font-size:11px;outline:none;text-overflow:ellipsis}.dsh-ig-field-select select:focus{border-color:var(--ig-blue)}.dsh-ig-count-row{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}.dsh-ig-count-pill{height:34px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);font-size:12px;font-weight:600;color:#596277;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .15s}.dsh-ig-count-pill:hover{border-color:#9fb2ed;color:var(--ig-blue)}.dsh-ig-count-pill.is-active{border-color:var(--ig-blue);background:rgba(47,100,245,.08);color:var(--ig-blue);box-shadow:inset 0 0 0 1px var(--ig-blue)}
|
|
4113
4357
|
.dsh-ig-upload{height:92px;border:1px dashed #bcc6d9;border-radius:9px;background:rgba(255,255,255,.45);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;color:#7d879b;cursor:pointer}.dsh-ig-upload strong{font-size:11px;font-weight:570}.dsh-ig-upload small{font-size:9.5px}.dsh-ig-upload:hover,.dsh-ig-upload.is-dragging{border-color:var(--ig-blue);background:rgba(47,100,245,.05);color:var(--ig-blue)}
|
|
4114
4358
|
.dsh-ig-reference-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:8px}
|
|
4115
4359
|
.dsh-ig-reference-card{position:relative;aspect-ratio:1;border-radius:8px;overflow:hidden;background:#eef1f7;border:1px solid var(--ig-line)}
|
|
@@ -4148,6 +4392,23 @@ window.__ModuleLoader__.load({
|
|
|
4148
4392
|
.dsh-ig-workspace-checkbox{cursor:pointer;accent-color:#2f64f5;width:13.5px;height:13.5px;margin:0}
|
|
4149
4393
|
.dsh-ig-workspace-filter-text{font-weight:500;white-space:nowrap}
|
|
4150
4394
|
.dsh-ig-workspace-filter-badge{font-size:10px;font-weight:600;padding:1px 6px;border-radius:999px;background:color-mix(in srgb,currentColor 7%,transparent);color:#64748b;font-variant-numeric:tabular-nums}
|
|
4395
|
+
.dsh-ig-canvas-cluster{display:grid;gap:16px;align-items:center;justify-content:center;user-select:none;pointer-events:auto;flex-shrink:0}
|
|
4396
|
+
.dsh-ig-canvas-cluster[data-count="2"]{grid-template-columns:repeat(2,1fr);max-width:880px}
|
|
4397
|
+
.dsh-ig-canvas-cluster[data-count="3"],.dsh-ig-canvas-cluster[data-count="4"]{grid-template-columns:repeat(2,1fr);max-width:760px}
|
|
4398
|
+
.dsh-ig-canvas-item{position:relative;display:flex;align-items:center;justify-content:center;border-radius:10px;cursor:pointer;transition:transform .12s ease-out}
|
|
4399
|
+
.dsh-ig-canvas-item img{display:block;max-width:100%;max-height:360px;width:auto;height:auto;object-fit:contain;border-radius:10px;box-shadow:0 10px 30px rgba(25,35,63,.16);user-select:none;-webkit-user-drag:none;pointer-events:auto;transition:box-shadow .15s,outline .15s}
|
|
4400
|
+
.dsh-ig-canvas-item:hover img{box-shadow:0 14px 40px rgba(47,100,245,.2)}
|
|
4401
|
+
.dsh-ig-canvas-item.is-selected img{outline:3px solid var(--ig-blue);outline-offset:2px;box-shadow:0 14px 40px rgba(47,100,245,.35)}
|
|
4402
|
+
.dsh-ig-canvas-badge{position:absolute;top:10px;left:10px;background:rgba(15,23,42,.7);color:#fff;font-size:11px;font-weight:700;padding:2px 7px;border-radius:5px;backdrop-filter:blur(4px);pointer-events:none;transition:background .15s;z-index:2}
|
|
4403
|
+
.dsh-ig-canvas-item.is-selected .dsh-ig-canvas-badge{background:var(--ig-blue)}
|
|
4404
|
+
.dsh-ig-canvas-item-loading{width:260px;height:260px;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.45);border:1px solid var(--ig-line);border-radius:10px;color:#929bad}
|
|
4405
|
+
.dsh-ig-lightbox-nav{position:absolute;top:50%;transform:translateY(-50%);width:42px;height:42px;border-radius:50%;border:0;background:rgba(15,23,42,.65);color:#fff;display:grid;place-items:center;cursor:pointer;transition:background .15s,transform .15s;z-index:10;backdrop-filter:blur(4px)}
|
|
4406
|
+
.dsh-ig-lightbox-nav:hover{background:rgba(47,100,245,.85);transform:translateY(-50%) scale(1.08)}
|
|
4407
|
+
.dsh-ig-lightbox-nav.is-prev{left:18px}
|
|
4408
|
+
.dsh-ig-lightbox-nav.is-next{right:18px}
|
|
4409
|
+
.dsh-ig-save-gallery-btn{color:var(--ig-blue)!important;border-color:rgba(47,100,245,.35)!important;background:rgba(47,100,245,.06)!important}
|
|
4410
|
+
.dsh-ig-save-gallery-btn:hover{background:rgba(47,100,245,.12)!important}
|
|
4411
|
+
.dsh-ig-save-gallery-btn.is-saved{color:#64748b!important;border-color:var(--ig-line)!important;background:transparent!important}
|
|
4151
4412
|
`;
|
|
4152
4413
|
//#endregion
|
|
4153
4414
|
//#region lib/types/client/image-result-node.js
|