Merge branch 'master' into codex/puzzle-clear-template-runtime-fixes

# Conflicts:
#	.hermes/shared-memory/decision-log.md
#	.hermes/shared-memory/project-overview.md
#	docs/【开发运维】本地开发验证与生产运维-2026-05-15.md
#	scripts/dev.test.ts
#	server-rs/crates/api-server/src/creation_entry_config.rs
#	server-rs/crates/api-server/src/wooden_fish.rs
#	server-rs/crates/module-auth/src/lib.rs
#	server-rs/crates/spacetime-client/src/wooden_fish.rs
#	server-rs/crates/spacetime-module/src/auth/procedures.rs
#	src/components/custom-world-home/creationWorkShelf.ts
#	src/components/platform-entry/PlatformEntryFlowShellImpl.tsx
#	src/components/rpg-entry/rpgEntryWorldPresentation.ts
#	src/services/miniGameDraftGenerationProgress.test.ts
#	src/services/miniGameDraftGenerationProgress.ts
This commit is contained in:
2026-06-04 11:24:14 +08:00
451 changed files with 18452 additions and 5266 deletions

View File

@@ -21,10 +21,14 @@ import type {
import { isPlatformCreationTypeVisible } from '../platform-entry/platformEntryCreationTypes';
import {
buildCreationWorkShelfItems,
getCreationWorkShelfItemTime,
type CreationWorkShelfItem,
type CreationWorkShelfMetricId,
type CreationWorkShelfRuntimeState,
} from './creationWorkShelf';
import { CustomWorldCreationStartCard } from './CustomWorldCreationStartCard';
import {
CustomWorldCreationStartCard,
} from './CustomWorldCreationStartCard';
import { CustomWorldWorkCard } from './CustomWorldWorkCard';
import {
type CustomWorldWorkFilter,
@@ -34,6 +38,9 @@ import {
const WORK_GRID_CLASS =
'creation-work-list grid min-w-0 gap-3 sm:gap-3.5 xl:gap-4';
const WORK_METRIC_CACHE_KEY = 'genarrative.creationHub.publishedMetrics.v1';
const RECENT_CREATION_WINDOW_DAYS = 7;
const RECENT_CREATION_WINDOW_MS =
RECENT_CREATION_WINDOW_DAYS * 24 * 60 * 60 * 1000;
type WorkMetricSnapshot = Record<
string,
@@ -67,7 +74,9 @@ type CustomWorldCreationHubProps = {
onOpenJumpHopDetail?: (item: JumpHopWorkSummaryResponse) => void;
onDeleteJumpHop?: ((item: JumpHopWorkSummaryResponse) => void) | null;
woodenFishItems?: WoodenFishWorkSummaryResponse[];
onOpenWoodenFishDetail?: ((item: WoodenFishWorkSummaryResponse) => void) | null;
onOpenWoodenFishDetail?:
| ((item: WoodenFishWorkSummaryResponse) => void)
| null;
onDeleteWoodenFish?: ((item: WoodenFishWorkSummaryResponse) => void) | null;
puzzleClearItems?: PuzzleClearWorkSummaryResponse[];
onOpenPuzzleClearDetail?: ((item: PuzzleClearWorkSummaryResponse) => void) | null;
@@ -88,8 +97,10 @@ type CustomWorldCreationHubProps = {
onDeleteVisualNovel?: ((item: VisualNovelWorkSummary) => void) | null;
getWorkState?: (
item: CreationWorkShelfItem,
) => { isGenerating?: boolean; hasUnreadUpdate?: boolean } | null;
) => CreationWorkShelfRuntimeState | null;
onOpenShelfItem?: (item: CreationWorkShelfItem) => void;
// 中文注释:底部加号入口可传入后端作品架摘要,用于推导最近使用过的模板。
recentWorkItems?: CreationWorkShelfItem[];
mode?: 'full' | 'start-only' | 'works-only';
};
@@ -156,6 +167,7 @@ function writeWorkMetricSnapshot(items: CreationWorkShelfItem[]) {
}
}
/** 渲染底部加号创作入口页与草稿作品架,最近创作复用最近使用过的模板入口。 */
export function CustomWorldCreationHub({
items,
loading,
@@ -204,6 +216,7 @@ export function CustomWorldCreationHub({
onDeleteVisualNovel = null,
getWorkState,
onOpenShelfItem,
recentWorkItems: recentWorkSourceItems,
mode = 'full',
}: CustomWorldCreationHubProps) {
const [activeFilter, setActiveFilter] =
@@ -299,7 +312,6 @@ export function CustomWorldCreationHub({
puzzleClearItems,
puzzleItems,
rpgLibraryEntries,
onOpenSquareHoleDetail,
onOpenJumpHopDetail,
jumpHopItems,
woodenFishItems,
@@ -325,6 +337,21 @@ export function CustomWorldCreationHub({
),
[activeFilter, shelfItems],
);
// 中文注释:最近创作只取 7 天内作品架摘要,再推导模板 ID 复用模板入口卡片。
const recentCreationCutoffMs = Date.now() - RECENT_CREATION_WINDOW_MS;
const recentWorkItems =
mode === 'start-only'
? (recentWorkSourceItems ?? shelfItems)
.filter(
(item) =>
getCreationWorkShelfItemTime(item.updatedAt) >=
recentCreationCutoffMs,
)
.slice(0, 4)
: [];
const recentCreationTypeIds = [
...new Set(recentWorkItems.map((item) => item.kind)),
];
function handleOpenShelfItem(item: CreationWorkShelfItem) {
onOpenShelfItem?.(item);
@@ -394,6 +421,8 @@ export function CustomWorldCreationHub({
busy={createBusy}
entryConfig={entryConfig}
creationTypes={creationTypes}
recentCreationTypeIds={recentCreationTypeIds}
recentWindowDays={RECENT_CREATION_WINDOW_DAYS}
onCreateType={onCreateType}
/>
) : null}