auto-save 2026-05-27 15:26 (~3)

This commit is contained in:
2026-05-27 15:28:29 +08:00
parent fdef7f77e1
commit 52e7a01a7e
3 changed files with 40 additions and 10 deletions

View File

@@ -1,12 +1,5 @@
{ {
"entries": [ "entries": [
{
"files_changed": 1,
"hash": "ddaa795",
"message": "docs: record sharp text layout deployment",
"ts": "2026-05-20T19:20:47+08:00",
"type": "commit"
},
{ {
"files_changed": 1, "files_changed": 1,
"message": "Codex 会话活跃 · 最近命令codex · 分支 main · 1 项未提交变更 · 最近提交docs: record sharp text layout deployment", "message": "Codex 会话活跃 · 最近命令codex · 分支 main · 1 项未提交变更 · 最近提交docs: record sharp text layout deployment",
@@ -3194,6 +3187,13 @@
"message": "docs: codify marketing product baseline", "message": "docs: codify marketing product baseline",
"hash": "3035efc", "hash": "3035efc",
"files_changed": 3 "files_changed": 3
},
{
"ts": "2026-05-27T15:20:42+08:00",
"type": "commit",
"message": "auto-save 2026-05-27 15:20 (~3)",
"hash": "fdef7f7",
"files_changed": 3
} }
] ]
} }

View File

@@ -36,6 +36,32 @@ let isRestoring = false
// Position change threshold for history | 位置变化阈值 // Position change threshold for history | 位置变化阈值
const POSITION_THRESHOLD = 10 const POSITION_THRESHOLD = 10
const DEFAULT_NODE_DIMENSIONS = {
text: { width: 320, height: 220 },
image: { width: 320, height: 260 },
imageConfig: { width: 320, height: 280 },
video: { width: 320, height: 220 },
videoConfig: { width: 320, height: 260 },
llmConfig: { width: 360, height: 360 },
default: { width: 320, height: 240 }
}
const normalizeDimensions = (type, dimensions = {}) => {
const fallback = DEFAULT_NODE_DIMENSIONS[type] || DEFAULT_NODE_DIMENSIONS.default
const width = Number(dimensions.width)
const height = Number(dimensions.height)
return {
width: Number.isFinite(width) && width > 0 ? width : fallback.width,
height: Number.isFinite(height) && height > 0 ? height : fallback.height
}
}
const normalizeNodeForCanvas = (node) => ({
...node,
dimensions: normalizeDimensions(node.type, node.dimensions)
})
// Batch operation tracking | 批量操作跟踪 // Batch operation tracking | 批量操作跟踪
let isBatchOperation = false let isBatchOperation = false
let batchStartState = null let batchStartState = null
@@ -167,12 +193,14 @@ const checkSignificantChanges = (oldState, newState) => {
const createNode = (type, position, data = {}, rootProps = {}, now = Date.now()) => { const createNode = (type, position, data = {}, rootProps = {}, now = Date.now()) => {
const id = getNodeId() const id = getNodeId()
const { dimensions, ...nodeRootProps } = rootProps
return { return {
id, id,
type, type,
position, position,
...rootProps, ...nodeRootProps,
dimensions: normalizeDimensions(type, dimensions),
data: { data: {
...getDefaultNodeData(type), ...getDefaultNodeData(type),
...data, ...data,
@@ -416,7 +444,7 @@ export const loadProject = (projectId) => {
if (canvasData) { if (canvasData) {
// Restore nodes | 恢复节点 // Restore nodes | 恢复节点
nodes.value = canvasData.nodes || [] nodes.value = (canvasData.nodes || []).map(normalizeNodeForCanvas)
edges.value = canvasData.edges || [] edges.value = canvasData.edges || []
canvasViewport.value = canvasData.viewport || { x: 100, y: 50, zoom: 0.8 } canvasViewport.value = canvasData.viewport || { x: 100, y: 50, zoom: 0.8 }

View File

@@ -52,6 +52,7 @@
:max-zoom="2" :max-zoom="2"
:snap-to-grid="true" :snap-to-grid="true"
:snap-grid="[20, 20]" :snap-grid="[20, 20]"
:only-render-visible-elements="true"
@connect="onConnect" @connect="onConnect"
@node-click="onNodeClick" @node-click="onNodeClick"
@pane-click="onPaneClick" @pane-click="onPaneClick"
@@ -61,7 +62,7 @@
> >
<Background v-if="showGrid" :gap="20" :size="1" /> <Background v-if="showGrid" :gap="20" :size="1" />
<MiniMap <MiniMap
v-if="!isMobile" v-if="showMiniMap"
position="bottom-right" position="bottom-right"
:pannable="true" :pannable="true"
:zoomable="true" :zoomable="true"
@@ -473,6 +474,7 @@ const inputPlaceholder = '你可以试着说"帮我生成一个二次元的卡
// Quick suggestions | 快捷建议 // Quick suggestions | 快捷建议
const suggestionPage = ref(0) const suggestionPage = ref(0)
const suggestions = computed(() => QUICK_SUGGESTION_GROUPS[suggestionPage.value % QUICK_SUGGESTION_GROUPS.length]) const suggestions = computed(() => QUICK_SUGGESTION_GROUPS[suggestionPage.value % QUICK_SUGGESTION_GROUPS.length])
const showMiniMap = computed(() => !isMobile.value && nodes.value.length <= 120)
const refreshSuggestions = () => { const refreshSuggestions = () => {
suggestionPage.value = (suggestionPage.value + 1) % QUICK_SUGGESTION_GROUPS.length suggestionPage.value = (suggestionPage.value + 1) % QUICK_SUGGESTION_GROUPS.length