陶泥儿发布跨项目不再串状态

- useTaonierTab 增加 projectPathRef,在打包/订阅/发布各 await 之后与进度回调里比对当前项目,避免旧项目进度、结果与失败落进新项目面板
This commit is contained in:
2026-10-07 14:14:18 +08:00
parent 86649e50a7
commit 5bc52a3441
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { resolveTauriInvoke } from '../../../../app/tauri';
import type { GamePublishProgressState } from '../../../../components/game-distribution/GamePublishProgressDialog';
@@ -71,6 +71,15 @@ export function useTaonierTab({
setDraft([]);
setRuntimeNotice('');
}, [projectPath]);
/**
* 发布链路跨 `await` 后仍要判断「面板当前展示的还是不是发起发布时的那个项目」:这个 hook 挂在
* 面板根,切项目不卸载,旧项目的发布结果 / 进度 / 失败不能落进新项目的面板。
*/
const projectPathRef = useRef(projectPath);
useEffect(() => {
projectPathRef.current = projectPath;
}, [projectPath]);
const chat = useDirectProjectChatController({
enabled,
ensureConversationReadAllowed,
@@ -203,6 +212,8 @@ export function useTaonierTab({
});
return;
}
// 打包期间换了项目:这次结论属于上一个项目,进度不能写进新项目。
if (projectPathRef.current !== projectPath) return;
if (!built) {
// 打包自己会把校验红字 / 适配弹窗 / 失败现场交给用户,这里只收起进度。
setProgress(null);
@@ -218,6 +229,8 @@ export function useTaonierTab({
let unsubscribe: TauriEventUnsubscribe = () => undefined;
try {
unsubscribe = await subscribeGamePackageUploadProgress((event) => {
// 发布途中换项目:旧项目的上传进度不能落到新项目面板上。
if (projectPathRef.current !== projectPath) return;
setProgress({
phase: 'running',
message: event.message || '正在发布…',
@@ -235,6 +248,8 @@ export function useTaonierTab({
// 订阅失败只影响阶段条:发布本身照常进行,按钮上仍显示「正在发布…」。
}
try {
// 建立订阅期间换了项目:这次发布属于上一个项目,不提交、不写状态。
if (projectPathRef.current !== projectPath) return;
// `packageAll` 内部可能采纳一份更新的注册表表单(并已落盘);发布命令不再回读
// `.export/taonier.json`,所以文字字段与本地媒体路径都取这份权威表单,避免漂移。
const effectiveForm = taonier.getEffectiveForm() ?? form;
@@ -253,11 +268,15 @@ export function useTaonierTab({
priceMudPoints: online.priceMudPoints,
expectedPublicationRevision: online.revision,
});
// 发布期间换了项目:旧项目的结果属于旧项目,别落进新项目面板。
if (projectPathRef.current !== projectPath) return;
setPublishResult(next);
setProgress(null);
// 发布成功后重新读一次线上值:线上最近版本与状态要以平台为准。
void taonier.refreshOnline();
} catch (error) {
// 旧项目的发布失败不该记到新项目头上。
if (projectPathRef.current !== projectPath) return;
setProgress({
phase: 'failed',
message: '发布失败',