@deepblend/dsh-blender-ui 0.3.8 → 0.3.9

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.
Files changed (2) hide show
  1. package/lib/client.js +46 -6
  2. package/package.json +2 -2
package/lib/client.js CHANGED
@@ -542,6 +542,9 @@ window.__ModuleLoader__.load({
542
542
  'revisions.currentSuffix': ' (当前)',
543
543
  'revisions.missing': '没有这个 revision',
544
544
  'preview.noneForRevision': '这个 revision 还没有预览图(渲染一次预览即可)。',
545
+ 'preview.reading': '正在读取所选项目的预览…',
546
+ 'preview.readFailed': '未能读取这个项目的预览。刷新后重试;保存版本和未提交修改仍保留。',
547
+ 'preview.sourceMismatch': '预览回执与所选项目不一致。刷新后重试。',
545
548
  'preview.noPrevious': '还没有上一次渲染:再点一次「渲染预览」,或者先在某个更早的 revision 上渲一次。',
546
549
  'preview.notRenderedHere': '这个 revision 还没有由面板渲过预览(上方的「渲染预览」会生成第一张)。',
547
550
  'preview.rendering': '渲染中…',
@@ -1109,6 +1112,9 @@ window.__ModuleLoader__.load({
1109
1112
  'revisions.currentSuffix': ' (current)',
1110
1113
  'revisions.missing': 'no such revision',
1111
1114
  'preview.noneForRevision': 'This revision has no preview image yet (render a preview and it will).',
1115
+ 'preview.reading': 'Reading previews for the selected project…',
1116
+ 'preview.readFailed': 'Could not read this project’s previews. Refresh to retry; saved versions and unsaved edits are kept.',
1117
+ 'preview.sourceMismatch': 'The preview response does not match the selected project. Refresh to retry.',
1112
1118
  'preview.noPrevious': 'No previous render yet: press “Render preview” again, or render once on an earlier revision.',
1113
1119
  'preview.notRenderedHere': 'This revision has no preview rendered from this panel yet (the “Render preview” button above makes the first one).',
1114
1120
  'preview.rendering': 'Rendering…',
@@ -2522,7 +2528,7 @@ window.__ModuleLoader__.load({
2522
2528
  if (typeof payload?.hostApiVersion === 'number' && payload.hostApiVersion < EXPECTED_HOST_API) {
2523
2529
  return { status: 'stale', payload: null, error: staleHostError(expectedRoute, { payload, status: response.status }) }
2524
2530
  }
2525
- if (payload && payload.ok) return { status: 'ok', payload, error: null }
2531
+ if (payload && payload.ok && response.ok !== false) return { status: 'ok', payload, error: null }
2526
2532
  return {
2527
2533
  status: 'error',
2528
2534
  payload: null,
@@ -2602,6 +2608,8 @@ window.__ModuleLoader__.load({
2602
2608
  unfinishedJobs: [],
2603
2609
  previews: null,
2604
2610
  artifactBase: '',
2611
+ previewContext: null,
2612
+ previewReadStatus: 'idle',
2605
2613
  view: 'projects',
2606
2614
  projectId: null,
2607
2615
  activeProjectId: null,
@@ -2754,6 +2762,19 @@ window.__ModuleLoader__.load({
2754
2762
  }
2755
2763
  /** Change the snapshot and tell everyone. @param {object} patch */
2756
2764
  const set = (patch) => {
2765
+ // Automatic edit images are source snapshots too. They cannot override
2766
+ // fresh rows from another store, even when its project/revision IDs match.
2767
+ if (Object.hasOwn(patch, 'projectsRoot') && patch.projectsRoot !== data.projectsRoot) {
2768
+ patch = { ...patch, editorComparison: null }
2769
+ }
2770
+ // Retire the old source before selection/creation navigation can expose
2771
+ // it with a new project. A load supplies the complete new source atomically.
2772
+ if (!Object.hasOwn(patch, 'previews') && ['projectId', 'projectsRoot', 'activeProjectId']
2773
+ .some(key => Object.hasOwn(patch, key) && patch[key] !== data[key])) {
2774
+ const requested = Object.hasOwn(patch, 'projectId') ? patch.projectId : data.projectId
2775
+ const active = Object.hasOwn(patch, 'activeProjectId') ? patch.activeProjectId : data.activeProjectId
2776
+ patch = { ...patch, previews: null, artifactBase: '', previewContext: null, previewReadStatus: requested || active ? 'loading' : 'idle' }
2777
+ }
2757
2778
  if (['projectsRoot', 'activeProjectId', 'currentRevision', 'view', 'compareMode', 'compareLeft', 'compareRight']
2758
2779
  .some(key => Object.hasOwn(patch, key) && patch[key] !== data[key])) {
2759
2780
  diffSequence += 1
@@ -2846,6 +2867,7 @@ window.__ModuleLoader__.load({
2846
2867
  currentRevision: payload.selected ? payload.selected.currentRevision : null,
2847
2868
  jobs: payload.selected ? payload.selected.jobs || [] : [],
2848
2869
  unfinishedJobs: payload.selected ? payload.selected.unfinishedJobs || [] : [],
2870
+ previews: null, artifactBase: '', previewContext: null, previewReadStatus: active === null ? 'idle' : 'loading',
2849
2871
  }
2850
2872
  live = patch.unfinishedJobs.length > 0
2851
2873
 
@@ -2861,11 +2883,22 @@ window.__ModuleLoader__.load({
2861
2883
  }
2862
2884
  const previewResult = await readRoute(fetchImpl, `${projectRoute(active, '/previews')}?t=${tick}`, 'project.previews')
2863
2885
  if (previewResult.status === 'ok') {
2864
- patch.previews = previewResult.payload.previews ?? null
2865
- patch.artifactBase = previewResult.payload.artifactBase ?? ''
2866
- } else if (previewResult.status === 'stale') {
2867
- patch.status = 'stale'
2886
+ const result = previewResult.payload
2887
+ if (result.previews?.projectId === active && Array.isArray(result.previews.revisions)
2888
+ && (result.projectId === undefined || result.projectId === active)
2889
+ && result.artifactBase === `/deepblend/artifacts/${encodeURIComponent(active)}/`) {
2890
+ patch.previews = result.previews
2891
+ patch.artifactBase = result.artifactBase
2892
+ patch.previewContext = { projectId: active, projectsRoot: patch.projectsRoot }
2893
+ patch.previewReadStatus = 'ok'
2894
+ } else {
2895
+ patch.previewReadStatus = 'error'
2896
+ patch.error = { code: 'UI_PREVIEW_MISMATCH', message: t('preview.sourceMismatch') }
2897
+ }
2898
+ } else {
2899
+ patch.previewReadStatus = 'error'
2868
2900
  patch.error = previewResult.error
2901
+ if (previewResult.status === 'stale') patch.status = 'stale'
2869
2902
  }
2870
2903
  } else {
2871
2904
  patch.previews = null
@@ -3852,6 +3885,7 @@ window.__ModuleLoader__.load({
3852
3885
  void load()
3853
3886
  },
3854
3887
  stop() {
3888
+ loadSequence += 1
3855
3889
  diffSequence += 1
3856
3890
  closeCreationDraft()
3857
3891
  draftLifecycle?.removeEventListener?.('pagehide', closeCreationDraft)
@@ -4877,7 +4911,13 @@ window.__ModuleLoader__.load({
4877
4911
  const state = ctx.state
4878
4912
  const actions = ctx.actions
4879
4913
  const previews = state.previews
4880
- if (previews === null) return el('div', { 'data-view': 'preview', className: 'db-muted' }, t('common.noProject'))
4914
+ if (previews === null) {
4915
+ if (state.previewReadStatus === 'error') return el('div', { 'data-view': 'preview', 'data-preview-state': 'error', className: 'db-card' },
4916
+ el('div', { className: 'db-muted' }, t('preview.readFailed')),
4917
+ Button({ action: 'preview-reload', onClick: actions.reload, children: t('common.refresh') }))
4918
+ if (state.previewReadStatus === 'loading') return el('div', { 'data-view': 'preview', 'data-preview-state': 'loading', className: 'db-muted' }, t('preview.reading'))
4919
+ return el('div', { 'data-view': 'preview', className: 'db-muted' }, t('common.noProject'))
4920
+ }
4881
4921
  const revisions = previews.revisions
4882
4922
  const { left, right } = previewRevisionPair(state)
4883
4923
  const entryOf = id => revisions.find(entry => entry.revision === id) || null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepblend/dsh-blender-ui",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "type": "module",
5
5
  "description": "DeepBlend workbench UI: Host half (typed HTTP API) and Web Client half (sidebar, panels, tool cards).",
6
6
  "main": "lib/index.js",
@@ -19,7 +19,7 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@deepblend/dsh-blender-contracts": "0.3.8"
22
+ "@deepblend/dsh-blender-contracts": "0.3.9"
23
23
  },
24
24
  "license": "MIT",
25
25
  "repository": {