Merge remote-tracking branch 'origin/codex/tiaoyitiao' into codex/tiaoyitiao
# Conflicts: # docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md # server-rs/crates/spacetime-client/src/jump_hop.rs # server-rs/crates/spacetime-client/src/mapper/runtime.rs # server-rs/crates/spacetime-client/src/wooden_fish.rs # src/components/jump-hop-result/JumpHopResultView.test.tsx # src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx # src/components/platform-entry/PlatformEntryFlowShellImpl.tsx # src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx # src/components/unified-creation/workspaces/JumpHopCreationWorkspace.tsx # src/components/unified-creation/workspaces/JumpHopWorkspace.test.tsx
This commit is contained in:
@@ -296,26 +296,30 @@ pub(crate) fn build_creation_entry_config_record_from_rows(
|
||||
event_banners_json: header.event_banners_json,
|
||||
creation_types: creation_types
|
||||
.into_iter()
|
||||
.map(|item| module_runtime::CreationEntryTypeSnapshot {
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
subtitle: item.subtitle,
|
||||
badge: item.badge,
|
||||
image_src: item.image_src,
|
||||
visible: item.visible,
|
||||
open: item.open,
|
||||
sort_order: item.sort_order,
|
||||
category_id: creation_entry_text_or_default(
|
||||
item.category_id,
|
||||
module_runtime::DEFAULT_CREATION_ENTRY_CATEGORY_ID,
|
||||
),
|
||||
category_label: creation_entry_text_or_default(
|
||||
item.category_label,
|
||||
module_runtime::DEFAULT_CREATION_ENTRY_CATEGORY_LABEL,
|
||||
),
|
||||
category_sort_order: item.category_sort_order,
|
||||
updated_at_micros: item.updated_at.to_micros_since_unix_epoch(),
|
||||
unified_creation_spec_json: item.unified_creation_spec_json,
|
||||
.map(|item| {
|
||||
normalize_creation_entry_type_snapshot(
|
||||
module_runtime::CreationEntryTypeSnapshot {
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
subtitle: item.subtitle,
|
||||
badge: item.badge,
|
||||
image_src: item.image_src,
|
||||
visible: item.visible,
|
||||
open: item.open,
|
||||
sort_order: item.sort_order,
|
||||
category_id: creation_entry_text_or_default(
|
||||
item.category_id,
|
||||
module_runtime::DEFAULT_CREATION_ENTRY_CATEGORY_ID,
|
||||
),
|
||||
category_label: creation_entry_text_or_default(
|
||||
item.category_label,
|
||||
module_runtime::DEFAULT_CREATION_ENTRY_CATEGORY_LABEL,
|
||||
),
|
||||
category_sort_order: item.category_sort_order,
|
||||
updated_at_micros: item.updated_at.to_micros_since_unix_epoch(),
|
||||
unified_creation_spec_json: item.unified_creation_spec_json,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
updated_at_micros: header.updated_at.to_micros_since_unix_epoch(),
|
||||
@@ -353,20 +357,22 @@ fn map_creation_entry_config_snapshot(
|
||||
creation_types: snapshot
|
||||
.creation_types
|
||||
.into_iter()
|
||||
.map(|item| module_runtime::CreationEntryTypeSnapshot {
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
subtitle: item.subtitle,
|
||||
badge: item.badge,
|
||||
image_src: item.image_src,
|
||||
visible: item.visible,
|
||||
open: item.open,
|
||||
sort_order: item.sort_order,
|
||||
category_id: item.category_id,
|
||||
category_label: item.category_label,
|
||||
category_sort_order: item.category_sort_order,
|
||||
updated_at_micros: item.updated_at_micros,
|
||||
unified_creation_spec_json: item.unified_creation_spec_json,
|
||||
.map(|item| {
|
||||
normalize_creation_entry_type_snapshot(module_runtime::CreationEntryTypeSnapshot {
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
subtitle: item.subtitle,
|
||||
badge: item.badge,
|
||||
image_src: item.image_src,
|
||||
visible: item.visible,
|
||||
open: item.open,
|
||||
sort_order: item.sort_order,
|
||||
category_id: item.category_id,
|
||||
category_label: item.category_label,
|
||||
category_sort_order: item.category_sort_order,
|
||||
updated_at_micros: item.updated_at_micros,
|
||||
unified_creation_spec_json: item.unified_creation_spec_json,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
updated_at_micros: snapshot.updated_at_micros,
|
||||
@@ -380,6 +386,138 @@ fn creation_entry_text_or_default(value: Option<String>, default_value: &str) ->
|
||||
.unwrap_or_else(|| default_value.to_string())
|
||||
}
|
||||
|
||||
fn normalize_creation_entry_type_snapshot(
|
||||
item: module_runtime::CreationEntryTypeSnapshot,
|
||||
) -> module_runtime::CreationEntryTypeSnapshot {
|
||||
// 中文注释:旧库里残留的跳一跳系统默认入口行仍会从订阅缓存命中,这里统一做读模型纠偏,
|
||||
// 这样无论走订阅缓存还是 procedure 回退,创作页都只会看到新的跳一跳入口口径。
|
||||
if item.id == "jump-hop"
|
||||
&& item.title == "跳一跳"
|
||||
&& item.subtitle == "俯视角跳跃闯关"
|
||||
&& item.badge == "可创建"
|
||||
&& item.image_src == "/creation-type-references/puzzle.webp"
|
||||
&& item.visible
|
||||
&& item.open
|
||||
&& item.sort_order == 45
|
||||
{
|
||||
return module_runtime::CreationEntryTypeSnapshot {
|
||||
subtitle: "主题驱动平台跳跃".to_string(),
|
||||
image_src: "/creation-type-references/jump-hop.webp".to_string(),
|
||||
..item
|
||||
};
|
||||
}
|
||||
|
||||
item
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use spacetimedb_sdk::Timestamp;
|
||||
|
||||
fn build_creation_entry_header() -> CreationEntryConfig {
|
||||
CreationEntryConfig {
|
||||
config_id: "creation-entry-config".to_string(),
|
||||
start_title: "新建作品".to_string(),
|
||||
start_description: "选择模板后进入对应的创作表单。".to_string(),
|
||||
start_idle_badge: "模板 Tab".to_string(),
|
||||
start_busy_badge: "正在开启".to_string(),
|
||||
modal_title: "选择创作类型".to_string(),
|
||||
modal_description: "先选玩法类型,再进入对应创作工作台。".to_string(),
|
||||
updated_at: Timestamp::from_micros_since_unix_epoch(1_000_000),
|
||||
event_title: None,
|
||||
event_description: None,
|
||||
event_cover_image_src: None,
|
||||
event_prize_pool_mud_points: 0,
|
||||
event_starts_at_text: None,
|
||||
event_ends_at_text: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_old_jump_hop_row() -> CreationEntryTypeConfig {
|
||||
CreationEntryTypeConfig {
|
||||
id: "jump-hop".to_string(),
|
||||
title: "跳一跳".to_string(),
|
||||
subtitle: "俯视角跳跃闯关".to_string(),
|
||||
badge: "可创建".to_string(),
|
||||
image_src: "/creation-type-references/puzzle.webp".to_string(),
|
||||
visible: true,
|
||||
open: true,
|
||||
sort_order: 45,
|
||||
updated_at: Timestamp::from_micros_since_unix_epoch(2_000_000),
|
||||
category_id: Some("recommended".to_string()),
|
||||
category_label: Some("热门推荐".to_string()),
|
||||
category_sort_order: 20,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_creation_entry_config_record_from_rows_normalizes_old_jump_hop_row() {
|
||||
let record = build_creation_entry_config_record_from_rows(
|
||||
build_creation_entry_header(),
|
||||
vec![build_old_jump_hop_row()],
|
||||
);
|
||||
|
||||
let jump_hop = record
|
||||
.creation_types
|
||||
.iter()
|
||||
.find(|item| item.id == "jump-hop")
|
||||
.expect("should contain jump-hop");
|
||||
|
||||
assert_eq!(jump_hop.subtitle, "主题驱动平台跳跃");
|
||||
assert_eq!(jump_hop.image_src, "/creation-type-references/jump-hop.webp");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn map_creation_entry_config_snapshot_normalizes_old_jump_hop_snapshot() {
|
||||
let record = map_creation_entry_config_snapshot(CreationEntryConfigSnapshot {
|
||||
config_id: "creation-entry-config".to_string(),
|
||||
start_card: CreationEntryStartCardSnapshot {
|
||||
title: "新建作品".to_string(),
|
||||
description: "选择模板后进入对应的创作表单。".to_string(),
|
||||
idle_badge: "模板 Tab".to_string(),
|
||||
busy_badge: "正在开启".to_string(),
|
||||
},
|
||||
type_modal: CreationEntryTypeModalSnapshot {
|
||||
title: "选择创作类型".to_string(),
|
||||
description: "先选玩法类型,再进入对应创作工作台。".to_string(),
|
||||
},
|
||||
event_banner: CreationEntryEventBannerSnapshot {
|
||||
title: "主题创作赛".to_string(),
|
||||
description: "用温暖的色彩,捏出秋天的故事。".to_string(),
|
||||
cover_image_src: "/branding/taonier-logo-spiral-reference-concepts/taonier-spiral-bouncy-clay.png".to_string(),
|
||||
prize_pool_mud_points: 58_000,
|
||||
starts_at_text: "2024.10.20 10:00".to_string(),
|
||||
ends_at_text: "2024.11.20 23:59".to_string(),
|
||||
},
|
||||
creation_types: vec![CreationEntryTypeSnapshot {
|
||||
id: "jump-hop".to_string(),
|
||||
title: "跳一跳".to_string(),
|
||||
subtitle: "俯视角跳跃闯关".to_string(),
|
||||
badge: "可创建".to_string(),
|
||||
image_src: "/creation-type-references/puzzle.webp".to_string(),
|
||||
visible: true,
|
||||
open: true,
|
||||
sort_order: 45,
|
||||
category_id: "recommended".to_string(),
|
||||
category_label: "热门推荐".to_string(),
|
||||
category_sort_order: 20,
|
||||
updated_at_micros: 2_000_000,
|
||||
}],
|
||||
updated_at_micros: 1_000_000,
|
||||
});
|
||||
|
||||
let jump_hop = record
|
||||
.creation_types
|
||||
.iter()
|
||||
.find(|item| item.id == "jump-hop")
|
||||
.expect("should contain jump-hop");
|
||||
|
||||
assert_eq!(jump_hop.subtitle, "主题驱动平台跳跃");
|
||||
assert_eq!(jump_hop.image_src, "/creation-type-references/jump-hop.webp");
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_setting_procedure_result(
|
||||
result: RuntimeSettingProcedureResult,
|
||||
) -> Result<RuntimeSettingsRecord, SpacetimeClientError> {
|
||||
|
||||
Reference in New Issue
Block a user