add public work share links
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-27 22:49:13 +08:00
parent 271db02e4a
commit 1348b2e940
23 changed files with 1038 additions and 248 deletions

View File

@@ -38,6 +38,10 @@ import type {
CustomWorldLibraryEntry,
} from '../../../packages/shared/src/contracts/runtime';
import { buildCustomWorldPlayableCharacters } from '../../data/characterPresets';
import {
buildPublicWorkStagePath,
pushAppHistoryPath,
} from '../../routing/appPageRoutes';
import {
getPublicAuthUserByCode,
getPublicAuthUserById,
@@ -48,11 +52,11 @@ import {
getBigFishCreationSession,
streamBigFishCreationMessage,
} from '../../services/big-fish-creation';
import { listBigFishGallery } from '../../services/big-fish-gallery';
import {
advanceLocalBigFishRuntimeRun,
startLocalBigFishRuntimeRun,
} from '../../services/big-fish-runtime';
import { listBigFishGallery } from '../../services/big-fish-gallery';
import {
deleteBigFishWork,
listBigFishWorks,
@@ -70,6 +74,8 @@ import {
} from '../../services/miniGameDraftGenerationProgress';
import { getPlatformProfileDashboard } from '../../services/platform-entry/platformProfileClient';
import {
buildBigFishPublicWorkCode,
buildPuzzlePublicWorkCode,
isSameBigFishPublicWorkCode,
isSamePuzzlePublicWorkCode,
} from '../../services/publicWorkCode';
@@ -407,6 +413,7 @@ export function PlatformEntryFlowShellImpl({
handleContinueGame,
handleStartNewGame,
handleCustomWorldSelect,
initialPublicWorkCode,
}: PlatformEntryFlowShellProps) {
const authUi = useAuthUi();
const [showCreationTypeModal, setShowCreationTypeModal] = useState(false);
@@ -418,6 +425,10 @@ export function PlatformEntryFlowShellImpl({
>([]);
const [bigFishRun, setBigFishRun] =
useState<BigFishRuntimeSnapshotResponse | null>(null);
const [bigFishRuntimeShare, setBigFishRuntimeShare] = useState<{
title: string;
publicWorkCode: string;
} | null>(null);
const [isBigFishLoadingLibrary, setIsBigFishLoadingLibrary] = useState(false);
const [bigFishGenerationState, setBigFishGenerationState] =
useState<MiniGameDraftGenerationState | null>(null);
@@ -455,6 +466,7 @@ export function PlatformEntryFlowShellImpl({
readCustomWorldAgentUiState().activeSessionId &&
shouldRestoreCustomWorldAgentUiState(),
);
const handledInitialPublicWorkCodeRef = useRef<string | null>(null);
const platformBootstrap = usePlatformEntryBootstrap({
user: authUi?.user,
@@ -926,6 +938,12 @@ export function PlatformEntryFlowShellImpl({
);
setSelectedPuzzleDetail(galleryDetail.item);
setSelectionStage('puzzle-gallery-detail');
pushAppHistoryPath(
buildPublicWorkStagePath(
'puzzle-gallery-detail',
buildPuzzlePublicWorkCode(galleryDetail.item.profileId),
),
);
}
},
beforeExecuteAction: ({ payload }) => {
@@ -1002,6 +1020,7 @@ export function PlatformEntryFlowShellImpl({
setSelectedDetailEntry(null);
setBigFishWorks([]);
setBigFishRun(null);
setBigFishRuntimeShare(null);
setBigFishGenerationState(null);
setBigFishError(null);
setPuzzleOperation(null);
@@ -1118,6 +1137,7 @@ export function PlatformEntryFlowShellImpl({
}
setBigFishError(null);
setBigFishRuntimeShare(null);
setBigFishRun(startLocalBigFishRuntimeRun({ session: bigFishSession }));
setSelectionStage('big-fish-runtime');
}, [bigFishSession, setSelectionStage]);
@@ -1128,6 +1148,7 @@ export function PlatformEntryFlowShellImpl({
}
setBigFishError(null);
setBigFishRuntimeShare(null);
setBigFishRun(startLocalBigFishRuntimeRun({ session: bigFishSession }));
setSelectionStage('big-fish-runtime');
}, [bigFishRun, bigFishSession, setSelectionStage]);
@@ -1147,6 +1168,12 @@ export function PlatformEntryFlowShellImpl({
setPuzzleRun(startLocalPuzzleRun(item));
setPuzzleRuntimeReturnStage('puzzle-gallery-detail');
setSelectionStage('puzzle-runtime');
pushAppHistoryPath(
buildPublicWorkStagePath(
'puzzle-runtime',
buildPuzzlePublicWorkCode(item.profileId),
),
);
} catch (error) {
setPuzzleError(resolvePuzzleErrorMessage(error, '启动拼图玩法失败。'));
} finally {
@@ -1600,6 +1627,12 @@ export function PlatformEntryFlowShellImpl({
setSelectedPuzzleDetail(item);
setPuzzleDetailReturnTarget(returnTarget);
setSelectionStage('puzzle-gallery-detail');
pushAppHistoryPath(
buildPublicWorkStagePath(
'puzzle-gallery-detail',
buildPuzzlePublicWorkCode(item.profileId),
),
);
} catch (error) {
setPuzzleError(resolvePuzzleErrorMessage(error, '读取拼图详情失败。'));
} finally {
@@ -1640,17 +1673,25 @@ export function PlatformEntryFlowShellImpl({
const startBigFishRunFromWork = useCallback(
(item: BigFishWorkSummary) => {
const sessionId = item.sourceSessionId?.trim();
if (!sessionId) {
setBigFishError('当前作品缺少会话信息,暂时无法进入玩法。');
return;
}
const sessionId = item.sourceSessionId?.trim();
if (!sessionId) {
setBigFishError('当前作品缺少会话信息,暂时无法进入玩法。');
return;
}
setBigFishError(null);
bigFishFlow.setSession(null);
setBigFishRun(startLocalBigFishRuntimeRun({ work: item }));
setSelectionStage('big-fish-runtime');
},
const publicWorkCode = buildBigFishPublicWorkCode(item.sourceSessionId);
setBigFishError(null);
bigFishFlow.setSession(null);
setBigFishRuntimeShare({
title: item.title,
publicWorkCode,
});
setBigFishRun(startLocalBigFishRuntimeRun({ work: item }));
setSelectionStage('big-fish-runtime');
pushAppHistoryPath(
buildPublicWorkStagePath('big-fish-runtime', publicWorkCode),
);
},
[bigFishFlow, setSelectionStage],
);
@@ -1800,6 +1841,19 @@ export function PlatformEntryFlowShellImpl({
],
);
useEffect(() => {
const publicWorkCode = initialPublicWorkCode?.trim();
if (
!publicWorkCode ||
handledInitialPublicWorkCodeRef.current === publicWorkCode
) {
return;
}
handledInitialPublicWorkCodeRef.current = publicWorkCode;
void handlePublicCodeSearch(publicWorkCode);
}, [handlePublicCodeSearch, initialPublicWorkCode]);
const openBigFishDraft = useCallback(
async (item: BigFishWorkSummary) => {
setBigFishRun(null);
@@ -2288,6 +2342,10 @@ export function PlatformEntryFlowShellImpl({
<BigFishRuntimeShell
run={bigFishRun}
assetSlots={bigFishSession?.assetSlots ?? []}
shareTitle={bigFishRuntimeShare?.title ?? null}
sharePublicWorkCode={
bigFishRuntimeShare?.publicWorkCode ?? null
}
isBusy={isBigFishBusy}
error={bigFishError}
onBack={() => {

View File

@@ -41,6 +41,7 @@ export type SyncedAgentDraftResult = {
export type PlatformEntryFlowShellProps = {
selectionStage: SelectionStage;
setSelectionStage: (stage: SelectionStage) => void;
initialPublicWorkCode?: string | null;
hasSavedGame: boolean;
savedSnapshot: HydratedSavedGameSnapshot | null;
handleContinueGame: (snapshot?: HydratedSavedGameSnapshot | null) => void;