feat: add visible flag for works
This commit is contained in:
@@ -39,6 +39,8 @@
|
|||||||
- `sort_time_micros`
|
- `sort_time_micros`
|
||||||
- `detail_payload_json`
|
- `detail_payload_json`
|
||||||
|
|
||||||
|
作品源表新增 `visible` 可见性字段,默认 `true`。`visible` 属于源表 / source view 过滤条件,不作为统一公开契约默认返回字段;当 `visible=false` 时,对应作品不得进入 `public_work_gallery_entry` 和 `public_work_detail_entry`。
|
||||||
|
|
||||||
其中 `detail_payload_json` 只承载平台详情页展示扩展,不承载正式 runtime 配置、玩法规则或草稿真相。
|
其中 `detail_payload_json` 只承载平台详情页展示扩展,不承载正式 runtime 配置、玩法规则或草稿真相。
|
||||||
|
|
||||||
## 来源与兼容
|
## 来源与兼容
|
||||||
@@ -63,6 +65,7 @@
|
|||||||
- 旧 view 保留,不删除。
|
- 旧 view 保留,不删除。
|
||||||
- 旧 view 退到底层 source / 兼容职责。
|
- 旧 view 退到底层 source / 兼容职责。
|
||||||
- 新 `public_work_*` view 是 `api-server` 公开列表 / 详情的统一主读模型。
|
- 新 `public_work_*` view 是 `api-server` 公开列表 / 详情的统一主读模型。
|
||||||
|
- 各玩法 source view 只暴露 `visible=true` 的已发布作品;旧数据迁移默认补 `visible=true`,避免历史作品被误隐藏。
|
||||||
- 旧 `/api/runtime/<play>/gallery` 响应 shape 保持兼容,由 BFF mapper 把统一 cache 再映射回当前 DTO。
|
- 旧 `/api/runtime/<play>/gallery` 响应 shape 保持兼容,由 BFF mapper 把统一 cache 再映射回当前 DTO。
|
||||||
- 旧详情 / runtime / 点赞 / 游玩 / Remix 仍走玩法专用路径。
|
- 旧详情 / runtime / 点赞 / 游玩 / Remix 仍走玩法专用路径。
|
||||||
|
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ npm run check:server-rs-ddd
|
|||||||
|
|
||||||
- Rust 结构体:`BarkBattlePublishedConfigRow`
|
- Rust 结构体:`BarkBattlePublishedConfigRow`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/bark_battle/tables.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/bark_battle/tables.rs`
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `bark_battle_runtime_run`
|
### `bark_battle_runtime_run`
|
||||||
|
|
||||||
@@ -288,6 +289,7 @@ npm run check:server-rs-ddd
|
|||||||
- Rust 结构体:`BigFishCreationSession`
|
- Rust 结构体:`BigFishCreationSession`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/big_fish/tables.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/big_fish/tables.rs`
|
||||||
- 索引:`by_big_fish_session_owner_user_id`、`by_big_fish_session_stage`。公开广场 view 使用 `by_big_fish_session_stage` 读取已发布会话,避免扫整表。
|
- 索引:`by_big_fish_session_owner_user_id`、`by_big_fish_session_stage`。公开广场 view 使用 `by_big_fish_session_stage` 读取已发布会话,避免扫整表。
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `big_fish_event`
|
### `big_fish_event`
|
||||||
|
|
||||||
@@ -351,11 +353,13 @@ npm run check:server-rs-ddd
|
|||||||
- Rust 结构体:`CustomWorldGalleryEntry`
|
- Rust 结构体:`CustomWorldGalleryEntry`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/custom_world.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/custom_world.rs`
|
||||||
- 作用:自定义世界公开 source 读模型。统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该投影并映射成跨玩法契约;`/api/runtime/custom-world-gallery` 保留旧 HTTP shape,并从统一 public cache 映射回旧 DTO。旧 procedure 只用于兼容旧库缺少 gallery 读模型行时的一次性同步兜底。
|
- 作用:自定义世界公开 source 读模型。统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该投影并映射成跨玩法契约;`/api/runtime/custom-world-gallery` 保留旧 HTTP shape,并从统一 public cache 映射回旧 DTO。旧 procedure 只用于兼容旧库缺少 gallery 读模型行时的一次性同步兜底。
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `custom_world_profile`
|
### `custom_world_profile`
|
||||||
|
|
||||||
- Rust 结构体:`CustomWorldProfile`
|
- Rust 结构体:`CustomWorldProfile`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/custom_world.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/custom_world.rs`
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `custom_world_session`
|
### `custom_world_session`
|
||||||
|
|
||||||
@@ -410,6 +414,7 @@ npm run check:server-rs-ddd
|
|||||||
- 返回类型:`Vec<JumpHopGalleryViewRow>`
|
- 返回类型:`Vec<JumpHopGalleryViewRow>`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/jump_hop.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/jump_hop.rs`
|
||||||
- 说明:跳一跳公开详情兼容投影,包含作品、路径和素材字段;统一公开详情主路径通过 `public_work_detail_entry` 消费该 view,只保留平台详情页展示摘要。
|
- 说明:跳一跳公开详情兼容投影,包含作品、路径和素材字段;统一公开详情主路径通过 `public_work_detail_entry` 消费该 view,只保留平台详情页展示摘要。
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `wooden_fish_agent_session`
|
### `wooden_fish_agent_session`
|
||||||
|
|
||||||
@@ -445,6 +450,7 @@ npm run check:server-rs-ddd
|
|||||||
- 返回类型:`Vec<WoodenFishGalleryViewRow>`
|
- 返回类型:`Vec<WoodenFishGalleryViewRow>`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish.rs`
|
||||||
- 说明:敲木鱼公开详情兼容投影,包含敲击物图案、背景环境图、主题返回按钮图、敲击音效和飘字配置;统一公开详情主路径通过 `public_work_detail_entry` 消费该 view,只保留平台详情页展示摘要。
|
- 说明:敲木鱼公开详情兼容投影,包含敲击物图案、背景环境图、主题返回按钮图、敲击音效和飘字配置;统一公开详情主路径通过 `public_work_detail_entry` 消费该 view,只保留平台详情页展示摘要。
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `match3d_agent_message`
|
### `match3d_agent_message`
|
||||||
|
|
||||||
@@ -472,6 +478,7 @@ npm run check:server-rs-ddd
|
|||||||
- 返回类型:`Vec<Match3DGalleryViewRow>`
|
- 返回类型:`Vec<Match3DGalleryViewRow>`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/match3d.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/match3d.rs`
|
||||||
- 说明:抓大鹅公开 source 投影,只暴露 `publication_status = published` 的作品卡片字段;统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该 view 并映射成跨玩法契约。个人作品列表、详情、发布、点赞、游玩记录和 Remix 仍按原有 procedure / reducer 路径处理。
|
- 说明:抓大鹅公开 source 投影,只暴露 `publication_status = published` 的作品卡片字段;统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该 view 并映射成跨玩法契约。个人作品列表、详情、发布、点赞、游玩记录和 Remix 仍按原有 procedure / reducer 路径处理。
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `npc_state`
|
### `npc_state`
|
||||||
|
|
||||||
@@ -658,6 +665,7 @@ RPG 创作入口的配置 ID 是 `rpg`,当前 `visible=true`、`open=true`;
|
|||||||
结构化创作和 RPG 的 LLM JSON 链路默认不启用 Responses `web_search`;只有在明确需要联网增强时,才通过 `GENARRATIVE_RPG_LLM_WEB_SEARCH_ENABLED` 或 `GENARRATIVE_CREATION_AGENT_LLM_WEB_SEARCH_ENABLED` 显式打开。否则未开通工具的上游会先吐自然语言再返回 `ToolNotOpen`,这类失败要按上游工具不可用处理,不要误判成模型返回结果解析失败。
|
结构化创作和 RPG 的 LLM JSON 链路默认不启用 Responses `web_search`;只有在明确需要联网增强时,才通过 `GENARRATIVE_RPG_LLM_WEB_SEARCH_ENABLED` 或 `GENARRATIVE_CREATION_AGENT_LLM_WEB_SEARCH_ENABLED` 显式打开。否则未开通工具的上游会先吐自然语言再返回 `ToolNotOpen`,这类失败要按上游工具不可用处理,不要误判成模型返回结果解析失败。
|
||||||
|
|
||||||
统一公开作品 BFF 路由是 `GET /api/public-works` 与 `GET /api/public-works/{publicWorkCode}`,响应契约由 `shared-contracts::public_work` 和 `packages/shared/src/contracts/publicWork.ts` 共同维护。前端首期仍走 BFF HTTP,不直接订阅 SpacetimeDB;后续若允许浏览器直连订阅,也只能订阅 `public_work_gallery_entry` / `public_work_detail_entry` 这类稳定公开 read model,不能订阅 `puzzle_work_profile`、`custom_world_profile` 等源表后自行拼装列表。设计细节见 `docs/technical/【后端架构】统一公开作品ReadModel设计-2026-05-26.md`。
|
统一公开作品 BFF 路由是 `GET /api/public-works` 与 `GET /api/public-works/{publicWorkCode}`,响应契约由 `shared-contracts::public_work` 和 `packages/shared/src/contracts/publicWork.ts` 共同维护。前端首期仍走 BFF HTTP,不直接订阅 SpacetimeDB;后续若允许浏览器直连订阅,也只能订阅 `public_work_gallery_entry` / `public_work_detail_entry` 这类稳定公开 read model,不能订阅 `puzzle_work_profile`、`custom_world_profile` 等源表后自行拼装列表。设计细节见 `docs/technical/【后端架构】统一公开作品ReadModel设计-2026-05-26.md`。
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `quest_log`
|
### `quest_log`
|
||||||
|
|
||||||
@@ -710,6 +718,7 @@ RPG 创作入口的配置 ID 是 `rpg`,当前 `visible=true`、`open=true`;
|
|||||||
- 返回类型:`Vec<SquareHoleGalleryViewRow>`
|
- 返回类型:`Vec<SquareHoleGalleryViewRow>`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/square_hole.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/square_hole.rs`
|
||||||
- 说明:方洞挑战公开 source 投影,只暴露 `publication_status = published` 的作品卡片字段;统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该 view 并映射成跨玩法契约。个人作品列表、详情、发布、点赞、游玩记录和 Remix 仍按原有 procedure / reducer 路径处理。
|
- 说明:方洞挑战公开 source 投影,只暴露 `publication_status = published` 的作品卡片字段;统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该 view 并映射成跨玩法契约。个人作品列表、详情、发布、点赞、游玩记录和 Remix 仍按原有 procedure / reducer 路径处理。
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|
||||||
### `story_event`
|
### `story_event`
|
||||||
|
|
||||||
@@ -785,3 +794,4 @@ RPG 创作入口的配置 ID 是 `rpg`,当前 `visible=true`、`open=true`;
|
|||||||
- 返回类型:`Vec<VisualNovelGalleryViewRow>`
|
- 返回类型:`Vec<VisualNovelGalleryViewRow>`
|
||||||
- 源码:`server-rs/crates/spacetime-module/src/visual_novel.rs`
|
- 源码:`server-rs/crates/spacetime-module/src/visual_novel.rs`
|
||||||
- 说明:视觉小说公开 source 投影,只暴露 `publication_status = published` 的作品卡片字段,不把完整 `draft` 暴露给公开列表订阅;统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该 view 并映射成跨玩法契约。个人历史、详情、运行态和发布仍按原有 procedure / reducer 路径处理。
|
- 说明:视觉小说公开 source 投影,只暴露 `publication_status = published` 的作品卡片字段,不把完整 `draft` 暴露给公开列表订阅;统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该 view 并映射成跨玩法契约。个人历史、详情、运行态和发布仍按原有 procedure / reducer 路径处理。
|
||||||
|
- 字段变更:`visible` 控制是否进入公开列表 / 详情,默认 `true`;旧迁移数据由 `migration.rs` 补默认值。
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ pub struct BarkBattlePublishedConfigRow {
|
|||||||
pub created_at: __sdk::Timestamp,
|
pub created_at: __sdk::Timestamp,
|
||||||
pub updated_at: __sdk::Timestamp,
|
pub updated_at: __sdk::Timestamp,
|
||||||
pub published_at: __sdk::Timestamp,
|
pub published_at: __sdk::Timestamp,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for BarkBattlePublishedConfigRow {
|
impl __sdk::InModule for BarkBattlePublishedConfigRow {
|
||||||
@@ -41,6 +42,7 @@ pub struct BarkBattlePublishedConfigRowCols {
|
|||||||
pub created_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
pub created_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
||||||
pub updated_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
pub updated_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
||||||
pub published_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
pub published_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for BarkBattlePublishedConfigRow {
|
impl __sdk::__query_builder::HasCols for BarkBattlePublishedConfigRow {
|
||||||
@@ -65,6 +67,7 @@ impl __sdk::__query_builder::HasCols for BarkBattlePublishedConfigRow {
|
|||||||
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
||||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ pub struct BigFishCreationSession {
|
|||||||
pub remix_count: u32,
|
pub remix_count: u32,
|
||||||
pub like_count: u32,
|
pub like_count: u32,
|
||||||
pub published_at: Option<__sdk::Timestamp>,
|
pub published_at: Option<__sdk::Timestamp>,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for BigFishCreationSession {
|
impl __sdk::InModule for BigFishCreationSession {
|
||||||
@@ -53,6 +54,7 @@ pub struct BigFishCreationSessionCols {
|
|||||||
pub remix_count: __sdk::__query_builder::Col<BigFishCreationSession, u32>,
|
pub remix_count: __sdk::__query_builder::Col<BigFishCreationSession, u32>,
|
||||||
pub like_count: __sdk::__query_builder::Col<BigFishCreationSession, u32>,
|
pub like_count: __sdk::__query_builder::Col<BigFishCreationSession, u32>,
|
||||||
pub published_at: __sdk::__query_builder::Col<BigFishCreationSession, Option<__sdk::Timestamp>>,
|
pub published_at: __sdk::__query_builder::Col<BigFishCreationSession, Option<__sdk::Timestamp>>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<BigFishCreationSession, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for BigFishCreationSession {
|
impl __sdk::__query_builder::HasCols for BigFishCreationSession {
|
||||||
@@ -82,6 +84,7 @@ impl __sdk::__query_builder::HasCols for BigFishCreationSession {
|
|||||||
remix_count: __sdk::__query_builder::Col::new(table_name, "remix_count"),
|
remix_count: __sdk::__query_builder::Col::new(table_name, "remix_count"),
|
||||||
like_count: __sdk::__query_builder::Col::new(table_name, "like_count"),
|
like_count: __sdk::__query_builder::Col::new(table_name, "like_count"),
|
||||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ pub struct CustomWorldGalleryEntry {
|
|||||||
pub like_count: u32,
|
pub like_count: u32,
|
||||||
pub published_at: __sdk::Timestamp,
|
pub published_at: __sdk::Timestamp,
|
||||||
pub updated_at: __sdk::Timestamp,
|
pub updated_at: __sdk::Timestamp,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for CustomWorldGalleryEntry {
|
impl __sdk::InModule for CustomWorldGalleryEntry {
|
||||||
@@ -53,6 +54,7 @@ pub struct CustomWorldGalleryEntryCols {
|
|||||||
pub like_count: __sdk::__query_builder::Col<CustomWorldGalleryEntry, u32>,
|
pub like_count: __sdk::__query_builder::Col<CustomWorldGalleryEntry, u32>,
|
||||||
pub published_at: __sdk::__query_builder::Col<CustomWorldGalleryEntry, __sdk::Timestamp>,
|
pub published_at: __sdk::__query_builder::Col<CustomWorldGalleryEntry, __sdk::Timestamp>,
|
||||||
pub updated_at: __sdk::__query_builder::Col<CustomWorldGalleryEntry, __sdk::Timestamp>,
|
pub updated_at: __sdk::__query_builder::Col<CustomWorldGalleryEntry, __sdk::Timestamp>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<CustomWorldGalleryEntry, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for CustomWorldGalleryEntry {
|
impl __sdk::__query_builder::HasCols for CustomWorldGalleryEntry {
|
||||||
@@ -82,6 +84,7 @@ impl __sdk::__query_builder::HasCols for CustomWorldGalleryEntry {
|
|||||||
like_count: __sdk::__query_builder::Col::new(table_name, "like_count"),
|
like_count: __sdk::__query_builder::Col::new(table_name, "like_count"),
|
||||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ pub struct CustomWorldProfile {
|
|||||||
pub deleted_at: Option<__sdk::Timestamp>,
|
pub deleted_at: Option<__sdk::Timestamp>,
|
||||||
pub created_at: __sdk::Timestamp,
|
pub created_at: __sdk::Timestamp,
|
||||||
pub updated_at: __sdk::Timestamp,
|
pub updated_at: __sdk::Timestamp,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for CustomWorldProfile {
|
impl __sdk::InModule for CustomWorldProfile {
|
||||||
@@ -65,6 +66,7 @@ pub struct CustomWorldProfileCols {
|
|||||||
pub deleted_at: __sdk::__query_builder::Col<CustomWorldProfile, Option<__sdk::Timestamp>>,
|
pub deleted_at: __sdk::__query_builder::Col<CustomWorldProfile, Option<__sdk::Timestamp>>,
|
||||||
pub created_at: __sdk::__query_builder::Col<CustomWorldProfile, __sdk::Timestamp>,
|
pub created_at: __sdk::__query_builder::Col<CustomWorldProfile, __sdk::Timestamp>,
|
||||||
pub updated_at: __sdk::__query_builder::Col<CustomWorldProfile, __sdk::Timestamp>,
|
pub updated_at: __sdk::__query_builder::Col<CustomWorldProfile, __sdk::Timestamp>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<CustomWorldProfile, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for CustomWorldProfile {
|
impl __sdk::__query_builder::HasCols for CustomWorldProfile {
|
||||||
@@ -105,6 +107,7 @@ impl __sdk::__query_builder::HasCols for CustomWorldProfile {
|
|||||||
deleted_at: __sdk::__query_builder::Col::new(table_name, "deleted_at"),
|
deleted_at: __sdk::__query_builder::Col::new(table_name, "deleted_at"),
|
||||||
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
||||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ pub struct JumpHopWorkProfileRow {
|
|||||||
pub play_count: u32,
|
pub play_count: u32,
|
||||||
pub updated_at: __sdk::Timestamp,
|
pub updated_at: __sdk::Timestamp,
|
||||||
pub published_at: Option<__sdk::Timestamp>,
|
pub published_at: Option<__sdk::Timestamp>,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for JumpHopWorkProfileRow {
|
impl __sdk::InModule for JumpHopWorkProfileRow {
|
||||||
@@ -65,6 +66,7 @@ pub struct JumpHopWorkProfileRowCols {
|
|||||||
pub play_count: __sdk::__query_builder::Col<JumpHopWorkProfileRow, u32>,
|
pub play_count: __sdk::__query_builder::Col<JumpHopWorkProfileRow, u32>,
|
||||||
pub updated_at: __sdk::__query_builder::Col<JumpHopWorkProfileRow, __sdk::Timestamp>,
|
pub updated_at: __sdk::__query_builder::Col<JumpHopWorkProfileRow, __sdk::Timestamp>,
|
||||||
pub published_at: __sdk::__query_builder::Col<JumpHopWorkProfileRow, Option<__sdk::Timestamp>>,
|
pub published_at: __sdk::__query_builder::Col<JumpHopWorkProfileRow, Option<__sdk::Timestamp>>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<JumpHopWorkProfileRow, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for JumpHopWorkProfileRow {
|
impl __sdk::__query_builder::HasCols for JumpHopWorkProfileRow {
|
||||||
@@ -104,6 +106,7 @@ impl __sdk::__query_builder::HasCols for JumpHopWorkProfileRow {
|
|||||||
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
||||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ pub struct Match3DWorkProfileRow {
|
|||||||
pub updated_at: __sdk::Timestamp,
|
pub updated_at: __sdk::Timestamp,
|
||||||
pub published_at: Option<__sdk::Timestamp>,
|
pub published_at: Option<__sdk::Timestamp>,
|
||||||
pub generated_item_assets_json: Option<String>,
|
pub generated_item_assets_json: Option<String>,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Match3DWorkProfileRow {
|
impl __sdk::InModule for Match3DWorkProfileRow {
|
||||||
@@ -54,6 +55,7 @@ pub struct Match3DWorkProfileRowCols {
|
|||||||
pub published_at: __sdk::__query_builder::Col<Match3DWorkProfileRow, Option<__sdk::Timestamp>>,
|
pub published_at: __sdk::__query_builder::Col<Match3DWorkProfileRow, Option<__sdk::Timestamp>>,
|
||||||
pub generated_item_assets_json:
|
pub generated_item_assets_json:
|
||||||
__sdk::__query_builder::Col<Match3DWorkProfileRow, Option<String>>,
|
__sdk::__query_builder::Col<Match3DWorkProfileRow, Option<String>>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<Match3DWorkProfileRow, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for Match3DWorkProfileRow {
|
impl __sdk::__query_builder::HasCols for Match3DWorkProfileRow {
|
||||||
@@ -84,6 +86,7 @@ impl __sdk::__query_builder::HasCols for Match3DWorkProfileRow {
|
|||||||
table_name,
|
table_name,
|
||||||
"generated_item_assets_json",
|
"generated_item_assets_json",
|
||||||
),
|
),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ pub struct PuzzleWorkProfileRow {
|
|||||||
pub like_count: u32,
|
pub like_count: u32,
|
||||||
pub point_incentive_total_half_points: u64,
|
pub point_incentive_total_half_points: u64,
|
||||||
pub point_incentive_claimed_points: u64,
|
pub point_incentive_claimed_points: u64,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for PuzzleWorkProfileRow {
|
impl __sdk::InModule for PuzzleWorkProfileRow {
|
||||||
@@ -68,6 +69,7 @@ pub struct PuzzleWorkProfileRowCols {
|
|||||||
pub like_count: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u32>,
|
pub like_count: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u32>,
|
||||||
pub point_incentive_total_half_points: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u64>,
|
pub point_incentive_total_half_points: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u64>,
|
||||||
pub point_incentive_claimed_points: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u64>,
|
pub point_incentive_claimed_points: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u64>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<PuzzleWorkProfileRow, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for PuzzleWorkProfileRow {
|
impl __sdk::__query_builder::HasCols for PuzzleWorkProfileRow {
|
||||||
@@ -107,6 +109,7 @@ impl __sdk::__query_builder::HasCols for PuzzleWorkProfileRow {
|
|||||||
table_name,
|
table_name,
|
||||||
"point_incentive_claimed_points",
|
"point_incentive_claimed_points",
|
||||||
),
|
),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ pub struct SquareHoleWorkProfileRow {
|
|||||||
pub play_count: u32,
|
pub play_count: u32,
|
||||||
pub updated_at: __sdk::Timestamp,
|
pub updated_at: __sdk::Timestamp,
|
||||||
pub published_at: Option<__sdk::Timestamp>,
|
pub published_at: Option<__sdk::Timestamp>,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for SquareHoleWorkProfileRow {
|
impl __sdk::InModule for SquareHoleWorkProfileRow {
|
||||||
@@ -54,6 +55,7 @@ pub struct SquareHoleWorkProfileRowCols {
|
|||||||
pub updated_at: __sdk::__query_builder::Col<SquareHoleWorkProfileRow, __sdk::Timestamp>,
|
pub updated_at: __sdk::__query_builder::Col<SquareHoleWorkProfileRow, __sdk::Timestamp>,
|
||||||
pub published_at:
|
pub published_at:
|
||||||
__sdk::__query_builder::Col<SquareHoleWorkProfileRow, Option<__sdk::Timestamp>>,
|
__sdk::__query_builder::Col<SquareHoleWorkProfileRow, Option<__sdk::Timestamp>>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<SquareHoleWorkProfileRow, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for SquareHoleWorkProfileRow {
|
impl __sdk::__query_builder::HasCols for SquareHoleWorkProfileRow {
|
||||||
@@ -81,6 +83,7 @@ impl __sdk::__query_builder::HasCols for SquareHoleWorkProfileRow {
|
|||||||
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
||||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ pub struct VisualNovelWorkProfileRow {
|
|||||||
pub created_at: __sdk::Timestamp,
|
pub created_at: __sdk::Timestamp,
|
||||||
pub updated_at: __sdk::Timestamp,
|
pub updated_at: __sdk::Timestamp,
|
||||||
pub published_at: Option<__sdk::Timestamp>,
|
pub published_at: Option<__sdk::Timestamp>,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for VisualNovelWorkProfileRow {
|
impl __sdk::InModule for VisualNovelWorkProfileRow {
|
||||||
@@ -52,6 +53,7 @@ pub struct VisualNovelWorkProfileRowCols {
|
|||||||
pub updated_at: __sdk::__query_builder::Col<VisualNovelWorkProfileRow, __sdk::Timestamp>,
|
pub updated_at: __sdk::__query_builder::Col<VisualNovelWorkProfileRow, __sdk::Timestamp>,
|
||||||
pub published_at:
|
pub published_at:
|
||||||
__sdk::__query_builder::Col<VisualNovelWorkProfileRow, Option<__sdk::Timestamp>>,
|
__sdk::__query_builder::Col<VisualNovelWorkProfileRow, Option<__sdk::Timestamp>>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<VisualNovelWorkProfileRow, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for VisualNovelWorkProfileRow {
|
impl __sdk::__query_builder::HasCols for VisualNovelWorkProfileRow {
|
||||||
@@ -81,6 +83,7 @@ impl __sdk::__query_builder::HasCols for VisualNovelWorkProfileRow {
|
|||||||
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
||||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ pub struct WoodenFishWorkProfileRow {
|
|||||||
pub published_at: Option<__sdk::Timestamp>,
|
pub published_at: Option<__sdk::Timestamp>,
|
||||||
pub background_asset_json: Option<String>,
|
pub background_asset_json: Option<String>,
|
||||||
pub back_button_asset_json: Option<String>,
|
pub back_button_asset_json: Option<String>,
|
||||||
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for WoodenFishWorkProfileRow {
|
impl __sdk::InModule for WoodenFishWorkProfileRow {
|
||||||
@@ -65,6 +66,7 @@ pub struct WoodenFishWorkProfileRowCols {
|
|||||||
__sdk::__query_builder::Col<WoodenFishWorkProfileRow, Option<String>>,
|
__sdk::__query_builder::Col<WoodenFishWorkProfileRow, Option<String>>,
|
||||||
pub back_button_asset_json:
|
pub back_button_asset_json:
|
||||||
__sdk::__query_builder::Col<WoodenFishWorkProfileRow, Option<String>>,
|
__sdk::__query_builder::Col<WoodenFishWorkProfileRow, Option<String>>,
|
||||||
|
pub visible: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for WoodenFishWorkProfileRow {
|
impl __sdk::__query_builder::HasCols for WoodenFishWorkProfileRow {
|
||||||
@@ -114,6 +116,7 @@ impl __sdk::__query_builder::HasCols for WoodenFishWorkProfileRow {
|
|||||||
table_name,
|
table_name,
|
||||||
"back_button_asset_json",
|
"back_button_asset_json",
|
||||||
),
|
),
|
||||||
|
visible: __sdk::__query_builder::Col::new(table_name, "visible"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pub fn bark_battle_gallery_view(ctx: &AnonymousViewContext) -> Vec<BarkBattleGal
|
|||||||
.bark_battle_published_config()
|
.bark_battle_published_config()
|
||||||
.by_bark_battle_published_owner_user_id()
|
.by_bark_battle_published_owner_user_id()
|
||||||
.filter(""..)
|
.filter(""..)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(|row| match build_bark_battle_gallery_view_row(ctx, &row) {
|
.filter_map(|row| match build_bark_battle_gallery_view_row(ctx, &row) {
|
||||||
Ok(item) => Some(item),
|
Ok(item) => Some(item),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -260,6 +261,7 @@ fn publish_bark_battle_work_tx(
|
|||||||
created_at: published_at,
|
created_at: published_at,
|
||||||
updated_at: published_at,
|
updated_at: published_at,
|
||||||
published_at,
|
published_at,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
let mut published = published;
|
let mut published = published;
|
||||||
match ctx
|
match ctx
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
accessor = bark_battle_draft_config,
|
accessor = bark_battle_draft_config,
|
||||||
index(accessor = by_bark_battle_draft_owner_user_id, btree(columns = [owner_user_id])),
|
index(accessor = by_bark_battle_draft_owner_user_id, btree(columns = [owner_user_id])),
|
||||||
@@ -40,6 +42,9 @@ pub struct BarkBattlePublishedConfigRow {
|
|||||||
pub(crate) created_at: Timestamp,
|
pub(crate) created_at: Timestamp,
|
||||||
pub(crate) updated_at: Timestamp,
|
pub(crate) updated_at: Timestamp,
|
||||||
pub(crate) published_at: Timestamp,
|
pub(crate) published_at: Timestamp,
|
||||||
|
// ???????????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
pub(crate) visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ pub(crate) fn generate_big_fish_asset_tx(
|
|||||||
published_at: session.published_at,
|
published_at: session.published_at,
|
||||||
created_at: session.created_at,
|
created_at: session.created_at,
|
||||||
updated_at,
|
updated_at,
|
||||||
|
visible: session.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &session, next_session);
|
replace_big_fish_session(ctx, &session, next_session);
|
||||||
for event in readiness.events {
|
for event in readiness.events {
|
||||||
@@ -200,6 +201,7 @@ pub(crate) fn publish_big_fish_game_tx(
|
|||||||
published_at: Some(published_at),
|
published_at: Some(published_at),
|
||||||
created_at: session.created_at,
|
created_at: session.created_at,
|
||||||
updated_at: published_at,
|
updated_at: published_at,
|
||||||
|
visible: session.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &session, next_session);
|
replace_big_fish_session(ctx, &session, next_session);
|
||||||
for event in readiness.events {
|
for event in readiness.events {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ pub fn big_fish_gallery_view(ctx: &AnonymousViewContext) -> Vec<BigFishWorkSumma
|
|||||||
.big_fish_creation_session()
|
.big_fish_creation_session()
|
||||||
.by_big_fish_session_stage()
|
.by_big_fish_session_stage()
|
||||||
.filter(BigFishCreationStage::Published)
|
.filter(BigFishCreationStage::Published)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(|row| match build_big_fish_gallery_view_row(ctx, &row) {
|
.filter_map(|row| match build_big_fish_gallery_view_row(ctx, &row) {
|
||||||
Ok(snapshot) => Some(snapshot),
|
Ok(snapshot) => Some(snapshot),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -284,6 +285,7 @@ pub(crate) fn create_big_fish_session_tx(
|
|||||||
published_at: None,
|
published_at: None,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at: created_at,
|
updated_at: created_at,
|
||||||
|
visible: true,
|
||||||
});
|
});
|
||||||
ctx.db.big_fish_agent_message().insert(BigFishAgentMessage {
|
ctx.db.big_fish_agent_message().insert(BigFishAgentMessage {
|
||||||
message_id: input.welcome_message_id,
|
message_id: input.welcome_message_id,
|
||||||
@@ -492,6 +494,7 @@ pub(crate) fn submit_big_fish_message_tx(
|
|||||||
published_at: session.published_at,
|
published_at: session.published_at,
|
||||||
created_at: session.created_at,
|
created_at: session.created_at,
|
||||||
updated_at: submitted_at,
|
updated_at: submitted_at,
|
||||||
|
visible: session.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &session, next_session);
|
replace_big_fish_session(ctx, &session, next_session);
|
||||||
|
|
||||||
@@ -542,6 +545,7 @@ pub(crate) fn finalize_big_fish_agent_message_turn_tx(
|
|||||||
published_at: session.published_at,
|
published_at: session.published_at,
|
||||||
created_at: session.created_at,
|
created_at: session.created_at,
|
||||||
updated_at,
|
updated_at,
|
||||||
|
visible: session.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &session, next_session);
|
replace_big_fish_session(ctx, &session, next_session);
|
||||||
return Err(error_message.to_string());
|
return Err(error_message.to_string());
|
||||||
@@ -600,6 +604,7 @@ pub(crate) fn finalize_big_fish_agent_message_turn_tx(
|
|||||||
published_at: session.published_at,
|
published_at: session.published_at,
|
||||||
created_at: session.created_at,
|
created_at: session.created_at,
|
||||||
updated_at,
|
updated_at,
|
||||||
|
visible: session.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &session, next_session);
|
replace_big_fish_session(ctx, &session, next_session);
|
||||||
|
|
||||||
@@ -667,6 +672,7 @@ pub(crate) fn compile_big_fish_draft_tx(
|
|||||||
published_at: session.published_at,
|
published_at: session.published_at,
|
||||||
created_at: session.created_at,
|
created_at: session.created_at,
|
||||||
updated_at: compiled_at,
|
updated_at: compiled_at,
|
||||||
|
visible: session.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &session, next_session);
|
replace_big_fish_session(ctx, &session, next_session);
|
||||||
for event in readiness.events {
|
for event in readiness.events {
|
||||||
@@ -768,6 +774,7 @@ pub(crate) fn record_big_fish_play_tx(
|
|||||||
published_at: session.published_at,
|
published_at: session.published_at,
|
||||||
created_at: session.created_at,
|
created_at: session.created_at,
|
||||||
updated_at: played_at,
|
updated_at: played_at,
|
||||||
|
visible: session.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &session, next_session);
|
replace_big_fish_session(ctx, &session, next_session);
|
||||||
|
|
||||||
@@ -821,6 +828,7 @@ pub(crate) fn record_big_fish_like_tx(
|
|||||||
published_at: session.published_at,
|
published_at: session.published_at,
|
||||||
created_at: session.created_at,
|
created_at: session.created_at,
|
||||||
updated_at: liked_at,
|
updated_at: liked_at,
|
||||||
|
visible: session.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &session, next_session);
|
replace_big_fish_session(ctx, &session, next_session);
|
||||||
}
|
}
|
||||||
@@ -888,6 +896,7 @@ fn remix_big_fish_work_tx(
|
|||||||
published_at: source.published_at,
|
published_at: source.published_at,
|
||||||
created_at: source.created_at,
|
created_at: source.created_at,
|
||||||
updated_at: remixed_at,
|
updated_at: remixed_at,
|
||||||
|
visible: source.visible,
|
||||||
};
|
};
|
||||||
replace_big_fish_session(ctx, &source, next_source);
|
replace_big_fish_session(ctx, &source, next_source);
|
||||||
|
|
||||||
@@ -909,6 +918,7 @@ fn remix_big_fish_work_tx(
|
|||||||
published_at: None,
|
published_at: None,
|
||||||
created_at: remixed_at,
|
created_at: remixed_at,
|
||||||
updated_at: remixed_at,
|
updated_at: remixed_at,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
ctx.db.big_fish_creation_session().insert(target_session);
|
ctx.db.big_fish_creation_session().insert(target_session);
|
||||||
ctx.db.big_fish_agent_message().insert(BigFishAgentMessage {
|
ctx.db.big_fish_agent_message().insert(BigFishAgentMessage {
|
||||||
@@ -1238,6 +1248,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
|
visible: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
accessor = big_fish_creation_session,
|
accessor = big_fish_creation_session,
|
||||||
index(accessor = by_big_fish_session_owner_user_id, btree(columns = [owner_user_id])),
|
index(accessor = by_big_fish_session_owner_user_id, btree(columns = [owner_user_id])),
|
||||||
@@ -28,6 +30,9 @@ pub struct BigFishCreationSession {
|
|||||||
pub(crate) like_count: u32,
|
pub(crate) like_count: u32,
|
||||||
#[default(None::<Timestamp>)]
|
#[default(None::<Timestamp>)]
|
||||||
pub(crate) published_at: Option<Timestamp>,
|
pub(crate) published_at: Option<Timestamp>,
|
||||||
|
// ???????????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
pub(crate) visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ use crate::*;
|
|||||||
use spacetimedb::AnonymousViewContext;
|
use spacetimedb::AnonymousViewContext;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
accessor = custom_world_profile,
|
accessor = custom_world_profile,
|
||||||
index(accessor = by_custom_world_profile_owner_user_id, btree(columns = [owner_user_id])),
|
index(accessor = by_custom_world_profile_owner_user_id, btree(columns = [owner_user_id])),
|
||||||
@@ -42,6 +44,9 @@ pub struct CustomWorldProfile {
|
|||||||
deleted_at: Option<Timestamp>,
|
deleted_at: Option<Timestamp>,
|
||||||
created_at: Timestamp,
|
created_at: Timestamp,
|
||||||
updated_at: Timestamp,
|
updated_at: Timestamp,
|
||||||
|
// ??????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
@@ -192,6 +197,9 @@ pub struct CustomWorldGalleryEntry {
|
|||||||
like_count: u32,
|
like_count: u32,
|
||||||
published_at: Timestamp,
|
published_at: Timestamp,
|
||||||
updated_at: Timestamp,
|
updated_at: Timestamp,
|
||||||
|
// ??????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
visible: bool,
|
||||||
}
|
}
|
||||||
// Agent 会话首版只负责把可持久化创作状态落进 SpacetimeDB,LLM 采集与卡片生成后续再接入。
|
// Agent 会话首版只负责把可持久化创作状态落进 SpacetimeDB,LLM 采集与卡片生成后续再接入。
|
||||||
#[spacetimedb::procedure]
|
#[spacetimedb::procedure]
|
||||||
@@ -1229,6 +1237,7 @@ fn upsert_custom_world_profile_record(
|
|||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
created_at: existing.created_at,
|
created_at: existing.created_at,
|
||||||
updated_at,
|
updated_at,
|
||||||
|
visible: existing.visible,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => CustomWorldProfile {
|
None => CustomWorldProfile {
|
||||||
@@ -1254,6 +1263,7 @@ fn upsert_custom_world_profile_record(
|
|||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
created_at: updated_at,
|
created_at: updated_at,
|
||||||
updated_at,
|
updated_at,
|
||||||
|
visible: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1401,6 +1411,7 @@ fn publish_custom_world_profile_record(
|
|||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
created_at: existing.created_at,
|
created_at: existing.created_at,
|
||||||
updated_at: published_at,
|
updated_at: published_at,
|
||||||
|
visible: existing.visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted = ctx.db.custom_world_profile().insert(next_row);
|
let inserted = ctx.db.custom_world_profile().insert(next_row);
|
||||||
@@ -1467,6 +1478,7 @@ fn unpublish_custom_world_profile_record(
|
|||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
created_at: existing.created_at,
|
created_at: existing.created_at,
|
||||||
updated_at,
|
updated_at,
|
||||||
|
visible: existing.visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted = ctx.db.custom_world_profile().insert(next_row);
|
let inserted = ctx.db.custom_world_profile().insert(next_row);
|
||||||
@@ -1529,6 +1541,7 @@ fn delete_custom_world_profile_record(
|
|||||||
deleted_at: Some(deleted_at),
|
deleted_at: Some(deleted_at),
|
||||||
created_at: existing.created_at,
|
created_at: existing.created_at,
|
||||||
updated_at: deleted_at,
|
updated_at: deleted_at,
|
||||||
|
visible: existing.visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = ctx.db.custom_world_profile().insert(next_row);
|
let _ = ctx.db.custom_world_profile().insert(next_row);
|
||||||
@@ -1651,6 +1664,7 @@ fn get_custom_world_gallery_detail_record(
|
|||||||
row.owner_user_id == input.owner_user_id
|
row.owner_user_id == input.owner_user_id
|
||||||
&& row.publication_status == CustomWorldPublicationStatus::Published
|
&& row.publication_status == CustomWorldPublicationStatus::Published
|
||||||
&& row.deleted_at.is_none()
|
&& row.deleted_at.is_none()
|
||||||
|
&& row.visible
|
||||||
});
|
});
|
||||||
|
|
||||||
let gallery_entry = ctx
|
let gallery_entry = ctx
|
||||||
@@ -1745,6 +1759,7 @@ fn remix_custom_world_profile_record(
|
|||||||
.filter(|row| {
|
.filter(|row| {
|
||||||
row.publication_status == CustomWorldPublicationStatus::Published
|
row.publication_status == CustomWorldPublicationStatus::Published
|
||||||
&& row.deleted_at.is_none()
|
&& row.deleted_at.is_none()
|
||||||
|
&& row.visible
|
||||||
&& row.published_at.is_some()
|
&& row.published_at.is_some()
|
||||||
})
|
})
|
||||||
.ok_or_else(|| "custom_world 已发布源作品不存在,无法改编".to_string())?;
|
.ok_or_else(|| "custom_world 已发布源作品不存在,无法改编".to_string())?;
|
||||||
@@ -1777,6 +1792,7 @@ fn remix_custom_world_profile_record(
|
|||||||
deleted_at: source.deleted_at,
|
deleted_at: source.deleted_at,
|
||||||
created_at: source.created_at,
|
created_at: source.created_at,
|
||||||
updated_at: remixed_at,
|
updated_at: remixed_at,
|
||||||
|
visible: source.visible,
|
||||||
};
|
};
|
||||||
let updated_source = ctx.db.custom_world_profile().insert(next_source);
|
let updated_source = ctx.db.custom_world_profile().insert(next_source);
|
||||||
let source_gallery = sync_custom_world_gallery_entry_from_profile(ctx, &updated_source)?;
|
let source_gallery = sync_custom_world_gallery_entry_from_profile(ctx, &updated_source)?;
|
||||||
@@ -1805,6 +1821,7 @@ fn remix_custom_world_profile_record(
|
|||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
created_at: remixed_at,
|
created_at: remixed_at,
|
||||||
updated_at: remixed_at,
|
updated_at: remixed_at,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(existing_target) = ctx
|
if let Some(existing_target) = ctx
|
||||||
@@ -1845,6 +1862,7 @@ fn record_custom_world_profile_play_record(
|
|||||||
.filter(|row| {
|
.filter(|row| {
|
||||||
row.publication_status == CustomWorldPublicationStatus::Published
|
row.publication_status == CustomWorldPublicationStatus::Published
|
||||||
&& row.deleted_at.is_none()
|
&& row.deleted_at.is_none()
|
||||||
|
&& row.visible
|
||||||
&& row.published_at.is_some()
|
&& row.published_at.is_some()
|
||||||
})
|
})
|
||||||
.ok_or_else(|| "custom_world 已发布作品不存在,无法记录游玩".to_string())?;
|
.ok_or_else(|| "custom_world 已发布作品不存在,无法记录游玩".to_string())?;
|
||||||
@@ -1887,6 +1905,7 @@ fn record_custom_world_profile_play_record(
|
|||||||
deleted_at: existing.deleted_at,
|
deleted_at: existing.deleted_at,
|
||||||
created_at: existing.created_at,
|
created_at: existing.created_at,
|
||||||
updated_at: played_at,
|
updated_at: played_at,
|
||||||
|
visible: existing.visible,
|
||||||
};
|
};
|
||||||
let inserted = ctx.db.custom_world_profile().insert(next_row);
|
let inserted = ctx.db.custom_world_profile().insert(next_row);
|
||||||
let gallery_entry = sync_custom_world_gallery_entry_from_profile(ctx, &inserted)?;
|
let gallery_entry = sync_custom_world_gallery_entry_from_profile(ctx, &inserted)?;
|
||||||
@@ -1916,6 +1935,7 @@ fn record_custom_world_profile_like_record(
|
|||||||
.filter(|row| {
|
.filter(|row| {
|
||||||
row.publication_status == CustomWorldPublicationStatus::Published
|
row.publication_status == CustomWorldPublicationStatus::Published
|
||||||
&& row.deleted_at.is_none()
|
&& row.deleted_at.is_none()
|
||||||
|
&& row.visible
|
||||||
&& row.published_at.is_some()
|
&& row.published_at.is_some()
|
||||||
})
|
})
|
||||||
.ok_or_else(|| "custom_world 已发布作品不存在,无法点赞".to_string())?;
|
.ok_or_else(|| "custom_world 已发布作品不存在,无法点赞".to_string())?;
|
||||||
@@ -1967,6 +1987,7 @@ fn record_custom_world_profile_like_record(
|
|||||||
deleted_at: existing.deleted_at,
|
deleted_at: existing.deleted_at,
|
||||||
created_at: existing.created_at,
|
created_at: existing.created_at,
|
||||||
updated_at: liked_at,
|
updated_at: liked_at,
|
||||||
|
visible: existing.visible,
|
||||||
};
|
};
|
||||||
let inserted = ctx.db.custom_world_profile().insert(next_row);
|
let inserted = ctx.db.custom_world_profile().insert(next_row);
|
||||||
let gallery_entry = sync_custom_world_gallery_entry_from_profile(ctx, &inserted)?;
|
let gallery_entry = sync_custom_world_gallery_entry_from_profile(ctx, &inserted)?;
|
||||||
@@ -2582,6 +2603,7 @@ fn is_same_agent_draft_profile_candidate(
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
row.owner_user_id == owner_user_id
|
row.owner_user_id == owner_user_id
|
||||||
&& row.deleted_at.is_none()
|
&& row.deleted_at.is_none()
|
||||||
|
&& row.visible
|
||||||
&& row.publication_status == CustomWorldPublicationStatus::Draft
|
&& row.publication_status == CustomWorldPublicationStatus::Draft
|
||||||
&& row.source_agent_session_id.as_deref() == Some(source_agent_session_id)
|
&& row.source_agent_session_id.as_deref() == Some(source_agent_session_id)
|
||||||
}
|
}
|
||||||
@@ -4841,6 +4863,7 @@ fn sync_custom_world_gallery_entry_from_profile(
|
|||||||
like_count: profile.like_count,
|
like_count: profile.like_count,
|
||||||
published_at,
|
published_at,
|
||||||
updated_at: profile.updated_at,
|
updated_at: profile.updated_at,
|
||||||
|
visible: profile.visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted = ctx.db.custom_world_gallery_entry().insert(row);
|
let inserted = ctx.db.custom_world_gallery_entry().insert(row);
|
||||||
@@ -4854,7 +4877,7 @@ fn sync_missing_custom_world_gallery_entries(ctx: &ReducerContext) -> Result<(),
|
|||||||
.custom_world_profile()
|
.custom_world_profile()
|
||||||
.by_custom_world_profile_publication_status()
|
.by_custom_world_profile_publication_status()
|
||||||
.filter(CustomWorldPublicationStatus::Published)
|
.filter(CustomWorldPublicationStatus::Published)
|
||||||
.filter(|profile| profile.deleted_at.is_none())
|
.filter(|profile| profile.deleted_at.is_none() && profile.visible)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for profile in published_profiles {
|
for profile in published_profiles {
|
||||||
@@ -4926,6 +4949,7 @@ fn ensure_custom_world_profile_public_fields(
|
|||||||
deleted_at: profile.deleted_at,
|
deleted_at: profile.deleted_at,
|
||||||
created_at: profile.created_at,
|
created_at: profile.created_at,
|
||||||
updated_at: profile.updated_at,
|
updated_at: profile.updated_at,
|
||||||
|
visible: profile.visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.db.custom_world_profile().insert(next_row)
|
ctx.db.custom_world_profile().insert(next_row)
|
||||||
@@ -4955,6 +4979,7 @@ fn build_custom_world_profile_row_copy(profile: &CustomWorldProfile) -> CustomWo
|
|||||||
deleted_at: profile.deleted_at,
|
deleted_at: profile.deleted_at,
|
||||||
created_at: profile.created_at,
|
created_at: profile.created_at,
|
||||||
updated_at: profile.updated_at,
|
updated_at: profile.updated_at,
|
||||||
|
visible: profile.visible,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4997,7 +5022,7 @@ pub(crate) fn custom_world_public_profile_snapshots(
|
|||||||
.custom_world_profile()
|
.custom_world_profile()
|
||||||
.by_custom_world_profile_publication_status()
|
.by_custom_world_profile_publication_status()
|
||||||
.filter(CustomWorldPublicationStatus::Published)
|
.filter(CustomWorldPublicationStatus::Published)
|
||||||
.filter(|row| row.deleted_at.is_none())
|
.filter(|row| row.deleted_at.is_none() && row.visible)
|
||||||
.map(|row| build_custom_world_profile_snapshot(&row))
|
.map(|row| build_custom_world_profile_snapshot(&row))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
@@ -5156,6 +5181,7 @@ pub(crate) fn custom_world_public_gallery_snapshots(
|
|||||||
.custom_world_gallery_entry()
|
.custom_world_gallery_entry()
|
||||||
.by_custom_world_gallery_owner_user_id()
|
.by_custom_world_gallery_owner_user_id()
|
||||||
.filter(""..)
|
.filter(""..)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.map(|row| {
|
.map(|row| {
|
||||||
build_custom_world_gallery_entry_snapshot_with_recent_counts(&row, &HashMap::new())
|
build_custom_world_gallery_entry_snapshot_with_recent_counts(&row, &HashMap::new())
|
||||||
})
|
})
|
||||||
@@ -5377,6 +5403,7 @@ mod tests {
|
|||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
let deleted = CustomWorldProfile {
|
let deleted = CustomWorldProfile {
|
||||||
profile_id: "profile-1".to_string(),
|
profile_id: "profile-1".to_string(),
|
||||||
@@ -5401,6 +5428,7 @@ mod tests {
|
|||||||
deleted_at: Some(Timestamp::from_micros_since_unix_epoch(2)),
|
deleted_at: Some(Timestamp::from_micros_since_unix_epoch(2)),
|
||||||
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
let published = CustomWorldProfile {
|
let published = CustomWorldProfile {
|
||||||
profile_id: "profile-1".to_string(),
|
profile_id: "profile-1".to_string(),
|
||||||
@@ -5425,6 +5453,7 @@ mod tests {
|
|||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(is_same_agent_draft_profile_candidate(
|
assert!(is_same_agent_draft_profile_candidate(
|
||||||
@@ -5552,6 +5581,7 @@ mod tests {
|
|||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
let mut active_agent_session_ids = HashSet::new();
|
let mut active_agent_session_ids = HashSet::new();
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pub fn jump_hop_gallery_view(ctx: &AnonymousViewContext) -> Vec<JumpHopGalleryVi
|
|||||||
.jump_hop_work_profile()
|
.jump_hop_work_profile()
|
||||||
.by_jump_hop_work_publication_status()
|
.by_jump_hop_work_publication_status()
|
||||||
.filter(JUMP_HOP_PUBLICATION_PUBLISHED)
|
.filter(JUMP_HOP_PUBLICATION_PUBLISHED)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(|row| match build_gallery_view_row(&row) {
|
.filter_map(|row| match build_gallery_view_row(&row) {
|
||||||
Ok(item) => Some(item),
|
Ok(item) => Some(item),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -401,6 +402,7 @@ fn compile_jump_hop_draft_tx(
|
|||||||
play_count: 0,
|
play_count: 0,
|
||||||
updated_at: compiled_at,
|
updated_at: compiled_at,
|
||||||
published_at: None,
|
published_at: None,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
upsert_work(ctx, row);
|
upsert_work(ctx, row);
|
||||||
replace_session(
|
replace_session(
|
||||||
@@ -1163,6 +1165,7 @@ fn clone_work(row: &JumpHopWorkProfileRow) -> JumpHopWorkProfileRow {
|
|||||||
play_count: row.play_count,
|
play_count: row.play_count,
|
||||||
updated_at: row.updated_at,
|
updated_at: row.updated_at,
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
accessor = jump_hop_agent_session,
|
accessor = jump_hop_agent_session,
|
||||||
index(accessor = by_jump_hop_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
index(accessor = by_jump_hop_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
||||||
@@ -51,6 +53,9 @@ pub struct JumpHopWorkProfileRow {
|
|||||||
pub(crate) play_count: u32,
|
pub(crate) play_count: u32,
|
||||||
pub(crate) updated_at: Timestamp,
|
pub(crate) updated_at: Timestamp,
|
||||||
pub(crate) published_at: Option<Timestamp>,
|
pub(crate) published_at: Option<Timestamp>,
|
||||||
|
// ???????????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
pub(crate) visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ pub fn match3d_gallery_view(ctx: &AnonymousViewContext) -> Vec<Match3DGalleryVie
|
|||||||
.match3d_work_profile()
|
.match3d_work_profile()
|
||||||
.by_match3d_work_publication_status()
|
.by_match3d_work_publication_status()
|
||||||
.filter(MATCH3D_PUBLICATION_PUBLISHED)
|
.filter(MATCH3D_PUBLICATION_PUBLISHED)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(|row| match build_gallery_view_row(&row) {
|
.filter_map(|row| match build_gallery_view_row(&row) {
|
||||||
Ok(item) => Some(item),
|
Ok(item) => Some(item),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -571,6 +572,7 @@ fn compile_match3d_draft_tx(
|
|||||||
updated_at: compiled_at,
|
updated_at: compiled_at,
|
||||||
published_at: previous_published_at,
|
published_at: previous_published_at,
|
||||||
generated_item_assets_json,
|
generated_item_assets_json,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
upsert_work(ctx, work);
|
upsert_work(ctx, work);
|
||||||
replace_session(
|
replace_session(
|
||||||
@@ -643,6 +645,7 @@ fn build_updated_match3d_work_row(
|
|||||||
updated_at,
|
updated_at,
|
||||||
published_at: current.published_at,
|
published_at: current.published_at,
|
||||||
generated_item_assets_json: current.generated_item_assets_json.clone(),
|
generated_item_assets_json: current.generated_item_assets_json.clone(),
|
||||||
|
visible: current.visible,
|
||||||
};
|
};
|
||||||
Ok(next)
|
Ok(next)
|
||||||
}
|
}
|
||||||
@@ -1330,6 +1333,7 @@ fn clone_work(row: &Match3DWorkProfileRow) -> Match3DWorkProfileRow {
|
|||||||
updated_at: row.updated_at,
|
updated_at: row.updated_at,
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
generated_item_assets_json: row.generated_item_assets_json.clone(),
|
generated_item_assets_json: row.generated_item_assets_json.clone(),
|
||||||
|
visible: row.visible,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1885,6 +1889,7 @@ mod tests {
|
|||||||
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
published_at: None,
|
published_at: None,
|
||||||
generated_item_assets_json: None,
|
generated_item_assets_json: None,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
let snapshot = build_initial_run_snapshot("run-1", &work, 10, None);
|
let snapshot = build_initial_run_snapshot("run-1", &work, 10, None);
|
||||||
assert_eq!(snapshot.total_item_count, 12);
|
assert_eq!(snapshot.total_item_count, 12);
|
||||||
@@ -1924,6 +1929,7 @@ mod tests {
|
|||||||
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"}]"#
|
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"}]"#
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let snapshot = build_work_snapshot(&work).expect("work snapshot should build");
|
let snapshot = build_work_snapshot(&work).expect("work snapshot should build");
|
||||||
@@ -1969,6 +1975,7 @@ mod tests {
|
|||||||
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"}]"#
|
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"}]"#
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let preserved =
|
let preserved =
|
||||||
@@ -2038,6 +2045,7 @@ mod tests {
|
|||||||
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"}]"#
|
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"}]"#
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
let input = Match3DWorkUpdateInput {
|
let input = Match3DWorkUpdateInput {
|
||||||
profile_id: existing.profile_id.clone(),
|
profile_id: existing.profile_id.clone(),
|
||||||
@@ -2097,6 +2105,7 @@ mod tests {
|
|||||||
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"},{"itemId":"match3d-item-2","itemName":"苹果","imageViews":[{"imageSrc":"/v1.png"},{"imageSrc":"/v2.png"},{"imageSrc":"/v3.png"},{"imageSrc":"/v4.png"},{"imageSrc":"/v5.png"}],"status":"model_ready"},{"itemId":"match3d-item-3","itemName":"香蕉","imageViews":[{"imageSrc":"/v1.png"},{"imageSrc":"/v2.png"},{"imageSrc":"/v3.png"},{"imageSrc":"/v4.png"}],"status":"image_ready"}]"#
|
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"},{"itemId":"match3d-item-2","itemName":"苹果","imageViews":[{"imageSrc":"/v1.png"},{"imageSrc":"/v2.png"},{"imageSrc":"/v3.png"},{"imageSrc":"/v4.png"},{"imageSrc":"/v5.png"}],"status":"model_ready"},{"itemId":"match3d-item-3","itemName":"香蕉","imageViews":[{"imageSrc":"/v1.png"},{"imageSrc":"/v2.png"},{"imageSrc":"/v3.png"},{"imageSrc":"/v4.png"}],"status":"image_ready"}]"#
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let error = validate_publishable_work(&base_work).unwrap_err();
|
let error = validate_publishable_work(&base_work).unwrap_err();
|
||||||
@@ -2156,6 +2165,7 @@ mod tests {
|
|||||||
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||||
published_at: None,
|
published_at: None,
|
||||||
generated_item_assets_json: None,
|
generated_item_assets_json: None,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let input_game_name = None;
|
let input_game_name = None;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
accessor = match3d_agent_session,
|
accessor = match3d_agent_session,
|
||||||
index(accessor = by_match3d_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
index(accessor = by_match3d_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
||||||
@@ -60,6 +62,9 @@ pub struct Match3DWorkProfileRow {
|
|||||||
pub(crate) published_at: Option<Timestamp>,
|
pub(crate) published_at: Option<Timestamp>,
|
||||||
#[default(None::<String>)]
|
#[default(None::<String>)]
|
||||||
pub(crate) generated_item_assets_json: Option<String>,
|
pub(crate) generated_item_assets_json: Option<String>,
|
||||||
|
// ???????????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
pub(crate) visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
|
|||||||
@@ -1257,6 +1257,10 @@ fn normalize_migration_row(table_name: &str, value: &serde_json::Value) -> serde
|
|||||||
}
|
}
|
||||||
if table_name == "puzzle_work_profile" {
|
if table_name == "puzzle_work_profile" {
|
||||||
if let Some(object) = next_value.as_object_mut() {
|
if let Some(object) = next_value.as_object_mut() {
|
||||||
|
// ???????????????????????????????
|
||||||
|
object
|
||||||
|
.entry("visible".to_string())
|
||||||
|
.or_insert_with(|| serde_json::Value::Bool(true));
|
||||||
// 中文注释:拼图公开互动计数晚于基础作品表加入,旧迁移包按 0 兼容。
|
// 中文注释:拼图公开互动计数晚于基础作品表加入,旧迁移包按 0 兼容。
|
||||||
object
|
object
|
||||||
.entry("play_count".to_string())
|
.entry("play_count".to_string())
|
||||||
@@ -1294,8 +1298,26 @@ fn normalize_migration_row(table_name: &str, value: &serde_json::Value) -> serde
|
|||||||
.or_insert(fallback_description);
|
.or_insert(fallback_description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if matches!(
|
||||||
|
table_name,
|
||||||
|
"jump_hop_work_profile"
|
||||||
|
| "square_hole_work_profile"
|
||||||
|
| "visual_novel_work_profile"
|
||||||
|
| "bark_battle_published_config"
|
||||||
|
) {
|
||||||
|
if let Some(object) = next_value.as_object_mut() {
|
||||||
|
// ???????????????????????????????
|
||||||
|
object
|
||||||
|
.entry("visible".to_string())
|
||||||
|
.or_insert_with(|| serde_json::Value::Bool(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
if table_name == "match3d_work_profile" {
|
if table_name == "match3d_work_profile" {
|
||||||
if let Some(object) = next_value.as_object_mut() {
|
if let Some(object) = next_value.as_object_mut() {
|
||||||
|
// ???????????????????????????????
|
||||||
|
object
|
||||||
|
.entry("visible".to_string())
|
||||||
|
.or_insert_with(|| serde_json::Value::Bool(true));
|
||||||
// 中文注释:抓大鹅生成素材字段晚于基础作品表加入,旧迁移包按未生成素材兼容。
|
// 中文注释:抓大鹅生成素材字段晚于基础作品表加入,旧迁移包按未生成素材兼容。
|
||||||
object
|
object
|
||||||
.entry("generated_item_assets_json".to_string())
|
.entry("generated_item_assets_json".to_string())
|
||||||
@@ -1304,6 +1326,10 @@ fn normalize_migration_row(table_name: &str, value: &serde_json::Value) -> serde
|
|||||||
}
|
}
|
||||||
if table_name == "wooden_fish_work_profile" {
|
if table_name == "wooden_fish_work_profile" {
|
||||||
if let Some(object) = next_value.as_object_mut() {
|
if let Some(object) = next_value.as_object_mut() {
|
||||||
|
// ???????????????????????????????
|
||||||
|
object
|
||||||
|
.entry("visible".to_string())
|
||||||
|
.or_insert_with(|| serde_json::Value::Bool(true));
|
||||||
// 中文注释:敲木鱼背景环境图晚于首版作品表加入,旧迁移包按未生成背景兼容。
|
// 中文注释:敲木鱼背景环境图晚于首版作品表加入,旧迁移包按未生成背景兼容。
|
||||||
object
|
object
|
||||||
.entry("background_asset_json".to_string())
|
.entry("background_asset_json".to_string())
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ use spacetimedb::{
|
|||||||
use crate::auth::user_account;
|
use crate::auth::user_account;
|
||||||
|
|
||||||
const PUZZLE_POINT_INCENTIVE_DEFAULT_U64: u64 = 0;
|
const PUZZLE_POINT_INCENTIVE_DEFAULT_U64: u64 = 0;
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
/// 拼图 Agent session 真相表。
|
/// 拼图 Agent session 真相表。
|
||||||
/// 当前只保存结构化字段与 JSON 草稿,不提前拆出更多编辑态子表。
|
/// 当前只保存结构化字段与 JSON 草稿,不提前拆出更多编辑态子表。
|
||||||
@@ -112,6 +113,9 @@ pub struct PuzzleWorkProfileRow {
|
|||||||
point_incentive_total_half_points: u64,
|
point_incentive_total_half_points: u64,
|
||||||
#[default(PUZZLE_POINT_INCENTIVE_DEFAULT_U64)]
|
#[default(PUZZLE_POINT_INCENTIVE_DEFAULT_U64)]
|
||||||
point_incentive_claimed_points: u64,
|
point_incentive_claimed_points: u64,
|
||||||
|
// ???????????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 拼图广场公开详情兼容投影。
|
/// 拼图广场公开详情兼容投影。
|
||||||
@@ -125,6 +129,7 @@ pub fn puzzle_gallery_view(ctx: &AnonymousViewContext) -> Vec<PuzzleWorkProfile>
|
|||||||
.puzzle_work_profile()
|
.puzzle_work_profile()
|
||||||
.by_puzzle_work_publication_status()
|
.by_puzzle_work_publication_status()
|
||||||
.filter(PuzzlePublicationStatus::Published)
|
.filter(PuzzlePublicationStatus::Published)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(
|
.filter_map(
|
||||||
|row| match build_puzzle_work_profile_from_row_without_recent_count(&row) {
|
|row| match build_puzzle_work_profile_from_row_without_recent_count(&row) {
|
||||||
Ok(profile) => Some(profile),
|
Ok(profile) => Some(profile),
|
||||||
@@ -154,6 +159,7 @@ pub fn puzzle_gallery_card_view(ctx: &AnonymousViewContext) -> Vec<PuzzleGallery
|
|||||||
.puzzle_work_profile()
|
.puzzle_work_profile()
|
||||||
.by_puzzle_work_publication_status()
|
.by_puzzle_work_publication_status()
|
||||||
.filter(PuzzlePublicationStatus::Published)
|
.filter(PuzzlePublicationStatus::Published)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(|row| match build_puzzle_gallery_card_view_row(&row) {
|
.filter_map(|row| match build_puzzle_gallery_card_view_row(&row) {
|
||||||
Ok(item) => Some(item),
|
Ok(item) => Some(item),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -1578,6 +1584,7 @@ fn update_puzzle_work_tx(
|
|||||||
created_at: row.created_at,
|
created_at: row.created_at,
|
||||||
updated_at: Timestamp::from_micros_since_unix_epoch(input.updated_at_micros),
|
updated_at: Timestamp::from_micros_since_unix_epoch(input.updated_at_micros),
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
};
|
};
|
||||||
replace_puzzle_work_profile(ctx, &row, next_row);
|
replace_puzzle_work_profile(ctx, &row, next_row);
|
||||||
sync_puzzle_source_session_draft_from_work(ctx, &row, &preview_draft, input.updated_at_micros)?;
|
sync_puzzle_source_session_draft_from_work(ctx, &row, &preview_draft, input.updated_at_micros)?;
|
||||||
@@ -1790,6 +1797,7 @@ fn record_puzzle_work_like_tx(
|
|||||||
created_at: row.created_at,
|
created_at: row.created_at,
|
||||||
updated_at: liked_at,
|
updated_at: liked_at,
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
};
|
};
|
||||||
replace_puzzle_work_profile(ctx, &row, next_row);
|
replace_puzzle_work_profile(ctx, &row, next_row);
|
||||||
ctx.db
|
ctx.db
|
||||||
@@ -1878,6 +1886,7 @@ fn remix_puzzle_work_tx(
|
|||||||
created_at: source.created_at,
|
created_at: source.created_at,
|
||||||
updated_at: remixed_at,
|
updated_at: remixed_at,
|
||||||
published_at: source.published_at,
|
published_at: source.published_at,
|
||||||
|
visible: source.visible,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1945,6 +1954,7 @@ fn remix_puzzle_work_tx(
|
|||||||
created_at: remixed_at,
|
created_at: remixed_at,
|
||||||
updated_at: remixed_at,
|
updated_at: remixed_at,
|
||||||
published_at: None,
|
published_at: None,
|
||||||
|
visible: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
get_puzzle_agent_session_tx(
|
get_puzzle_agent_session_tx(
|
||||||
@@ -2396,6 +2406,7 @@ fn claim_puzzle_work_point_incentive_tx(
|
|||||||
created_at: row.created_at,
|
created_at: row.created_at,
|
||||||
updated_at: claimed_at,
|
updated_at: claimed_at,
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
};
|
};
|
||||||
replace_puzzle_work_profile(ctx, &row, next_row);
|
replace_puzzle_work_profile(ctx, &row, next_row);
|
||||||
|
|
||||||
@@ -3008,6 +3019,7 @@ fn upsert_puzzle_work_profile(ctx: &TxContext, profile: PuzzleWorkProfile) -> Re
|
|||||||
published_at: profile
|
published_at: profile
|
||||||
.published_at_micros
|
.published_at_micros
|
||||||
.map(Timestamp::from_micros_since_unix_epoch),
|
.map(Timestamp::from_micros_since_unix_epoch),
|
||||||
|
visible: existing.visible,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -3040,6 +3052,7 @@ fn upsert_puzzle_work_profile(ctx: &TxContext, profile: PuzzleWorkProfile) -> Re
|
|||||||
published_at: profile
|
published_at: profile
|
||||||
.published_at_micros
|
.published_at_micros
|
||||||
.map(Timestamp::from_micros_since_unix_epoch),
|
.map(Timestamp::from_micros_since_unix_epoch),
|
||||||
|
visible: true,
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -3364,6 +3377,7 @@ fn accrue_puzzle_point_incentive(
|
|||||||
created_at: row.created_at,
|
created_at: row.created_at,
|
||||||
updated_at: Timestamp::from_micros_since_unix_epoch(updated_at_micros),
|
updated_at: Timestamp::from_micros_since_unix_epoch(updated_at_micros),
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -3402,6 +3416,7 @@ fn increment_puzzle_profile_play_count(
|
|||||||
created_at: row.created_at,
|
created_at: row.created_at,
|
||||||
updated_at: Timestamp::from_micros_since_unix_epoch(updated_at_micros),
|
updated_at: Timestamp::from_micros_since_unix_epoch(updated_at_micros),
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ pub fn square_hole_gallery_view(ctx: &AnonymousViewContext) -> Vec<SquareHoleGal
|
|||||||
.square_hole_work_profile()
|
.square_hole_work_profile()
|
||||||
.by_square_hole_work_publication_status()
|
.by_square_hole_work_publication_status()
|
||||||
.filter(SQUARE_HOLE_PUBLICATION_PUBLISHED)
|
.filter(SQUARE_HOLE_PUBLICATION_PUBLISHED)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(|row| match build_gallery_view_row(&row) {
|
.filter_map(|row| match build_gallery_view_row(&row) {
|
||||||
Ok(item) => Some(item),
|
Ok(item) => Some(item),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -537,6 +538,7 @@ fn compile_square_hole_draft_tx(
|
|||||||
play_count: 0,
|
play_count: 0,
|
||||||
updated_at: compiled_at,
|
updated_at: compiled_at,
|
||||||
published_at: None,
|
published_at: None,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
upsert_work(ctx, work);
|
upsert_work(ctx, work);
|
||||||
replace_session(
|
replace_session(
|
||||||
@@ -614,6 +616,7 @@ fn update_square_hole_work_tx(
|
|||||||
play_count: current.play_count,
|
play_count: current.play_count,
|
||||||
updated_at,
|
updated_at,
|
||||||
published_at: current.published_at,
|
published_at: current.published_at,
|
||||||
|
visible: current.visible,
|
||||||
};
|
};
|
||||||
let snapshot = build_work_snapshot(&next)?;
|
let snapshot = build_work_snapshot(&next)?;
|
||||||
replace_work(ctx, ¤t, next);
|
replace_work(ctx, ¤t, next);
|
||||||
@@ -1141,6 +1144,7 @@ fn clone_work(row: &SquareHoleWorkProfileRow) -> SquareHoleWorkProfileRow {
|
|||||||
play_count: row.play_count,
|
play_count: row.play_count,
|
||||||
updated_at: row.updated_at,
|
updated_at: row.updated_at,
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
accessor = square_hole_agent_session,
|
accessor = square_hole_agent_session,
|
||||||
index(accessor = by_square_hole_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
index(accessor = by_square_hole_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
||||||
@@ -59,6 +61,9 @@ pub struct SquareHoleWorkProfileRow {
|
|||||||
pub(crate) play_count: u32,
|
pub(crate) play_count: u32,
|
||||||
pub(crate) updated_at: Timestamp,
|
pub(crate) updated_at: Timestamp,
|
||||||
pub(crate) published_at: Option<Timestamp>,
|
pub(crate) published_at: Option<Timestamp>,
|
||||||
|
// ???????????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
pub(crate) visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
use serde::Serialize;
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use spacetimedb::AnonymousViewContext;
|
use spacetimedb::AnonymousViewContext;
|
||||||
|
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
pub const VISUAL_NOVEL_SOURCE_IDEA: &str = "idea";
|
pub const VISUAL_NOVEL_SOURCE_IDEA: &str = "idea";
|
||||||
pub const VISUAL_NOVEL_SOURCE_DOCUMENT: &str = "document";
|
pub const VISUAL_NOVEL_SOURCE_DOCUMENT: &str = "document";
|
||||||
pub const VISUAL_NOVEL_SOURCE_BLANK: &str = "blank";
|
pub const VISUAL_NOVEL_SOURCE_BLANK: &str = "blank";
|
||||||
@@ -94,6 +95,9 @@ pub struct VisualNovelWorkProfileRow {
|
|||||||
pub(crate) created_at: Timestamp,
|
pub(crate) created_at: Timestamp,
|
||||||
pub(crate) updated_at: Timestamp,
|
pub(crate) updated_at: Timestamp,
|
||||||
pub(crate) published_at: Option<Timestamp>,
|
pub(crate) published_at: Option<Timestamp>,
|
||||||
|
// ???????????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
pub(crate) visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 视觉小说运行态 run 表。
|
/// 视觉小说运行态 run 表。
|
||||||
@@ -178,6 +182,7 @@ pub fn visual_novel_gallery_view(ctx: &AnonymousViewContext) -> Vec<VisualNovelG
|
|||||||
.visual_novel_work_profile()
|
.visual_novel_work_profile()
|
||||||
.by_visual_novel_work_publication_status()
|
.by_visual_novel_work_publication_status()
|
||||||
.filter(VISUAL_NOVEL_PUBLICATION_PUBLISHED)
|
.filter(VISUAL_NOVEL_PUBLICATION_PUBLISHED)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(|row| match build_gallery_view_row(&row) {
|
.filter_map(|row| match build_gallery_view_row(&row) {
|
||||||
Ok(item) => Some(item),
|
Ok(item) => Some(item),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -421,13 +426,13 @@ pub struct VisualNovelRuntimeEventProcedureResult {
|
|||||||
pub error_message: Option<String>,
|
pub error_message: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, SpacetimeType)]
|
||||||
pub struct VisualNovelJsonField {
|
pub struct VisualNovelJsonField {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
pub value: VisualNovelJsonValue,
|
pub value: VisualNovelJsonValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, SpacetimeType)]
|
||||||
pub enum VisualNovelJsonValue {
|
pub enum VisualNovelJsonValue {
|
||||||
Null,
|
Null,
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
@@ -437,7 +442,7 @@ pub enum VisualNovelJsonValue {
|
|||||||
Object(Vec<VisualNovelJsonField>),
|
Object(Vec<VisualNovelJsonField>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, SpacetimeType)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct VisualNovelAgentMessageSnapshot {
|
pub struct VisualNovelAgentMessageSnapshot {
|
||||||
pub message_id: String,
|
pub message_id: String,
|
||||||
@@ -448,7 +453,7 @@ pub struct VisualNovelAgentMessageSnapshot {
|
|||||||
pub created_at_micros: i64,
|
pub created_at_micros: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, SpacetimeType)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct VisualNovelAgentSessionSnapshot {
|
pub struct VisualNovelAgentSessionSnapshot {
|
||||||
pub session_id: String,
|
pub session_id: String,
|
||||||
@@ -468,7 +473,7 @@ pub struct VisualNovelAgentSessionSnapshot {
|
|||||||
pub updated_at_micros: i64,
|
pub updated_at_micros: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, SpacetimeType)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct VisualNovelWorkSnapshot {
|
pub struct VisualNovelWorkSnapshot {
|
||||||
pub work_id: String,
|
pub work_id: String,
|
||||||
@@ -490,7 +495,7 @@ pub struct VisualNovelWorkSnapshot {
|
|||||||
pub published_at_micros: Option<i64>,
|
pub published_at_micros: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, SpacetimeType)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct VisualNovelRuntimeHistoryEntrySnapshot {
|
pub struct VisualNovelRuntimeHistoryEntrySnapshot {
|
||||||
pub entry_id: String,
|
pub entry_id: String,
|
||||||
@@ -506,7 +511,7 @@ pub struct VisualNovelRuntimeHistoryEntrySnapshot {
|
|||||||
pub created_at_micros: i64,
|
pub created_at_micros: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, SpacetimeType)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct VisualNovelRunSnapshot {
|
pub struct VisualNovelRunSnapshot {
|
||||||
pub run_id: String,
|
pub run_id: String,
|
||||||
@@ -526,7 +531,7 @@ pub struct VisualNovelRunSnapshot {
|
|||||||
pub updated_at_micros: i64,
|
pub updated_at_micros: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, SpacetimeType)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct VisualNovelRuntimeEventSnapshot {
|
pub struct VisualNovelRuntimeEventSnapshot {
|
||||||
pub event_id: String,
|
pub event_id: String,
|
||||||
@@ -1029,6 +1034,7 @@ fn compile_visual_novel_work_profile_tx(
|
|||||||
created_at: compiled_at,
|
created_at: compiled_at,
|
||||||
updated_at: compiled_at,
|
updated_at: compiled_at,
|
||||||
published_at: None,
|
published_at: None,
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
upsert_work(ctx, work);
|
upsert_work(ctx, work);
|
||||||
replace_session(
|
replace_session(
|
||||||
@@ -1731,6 +1737,7 @@ fn clone_work(row: &VisualNovelWorkProfileRow) -> VisualNovelWorkProfileRow {
|
|||||||
created_at: row.created_at,
|
created_at: row.created_at,
|
||||||
updated_at: row.updated_at,
|
updated_at: row.updated_at,
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1971,7 +1978,7 @@ fn parse_json<T: DeserializeOwned>(value: &str, label: &str) -> Result<T, String
|
|||||||
serde_json::from_str(value).map_err(|error| format!("{label} 非法: {error}"))
|
serde_json::from_str(value).map_err(|error| format!("{label} 非法: {error}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_json_string<T: Serialize>(value: &T) -> String {
|
fn to_json_string<T: serde::Serialize>(value: &T) -> String {
|
||||||
serde_json::to_string(value).unwrap_or_else(|_| "{}".to_string())
|
serde_json::to_string(value).unwrap_or_else(|_| "{}".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pub fn wooden_fish_gallery_view(ctx: &AnonymousViewContext) -> Vec<WoodenFishGal
|
|||||||
.wooden_fish_work_profile()
|
.wooden_fish_work_profile()
|
||||||
.by_wooden_fish_work_publication_status()
|
.by_wooden_fish_work_publication_status()
|
||||||
.filter(WOODEN_FISH_PUBLICATION_PUBLISHED)
|
.filter(WOODEN_FISH_PUBLICATION_PUBLISHED)
|
||||||
|
.filter(|row| row.visible)
|
||||||
.filter_map(|row| match build_gallery_view_row(&row) {
|
.filter_map(|row| match build_gallery_view_row(&row) {
|
||||||
Ok(item) => Some(item),
|
Ok(item) => Some(item),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -408,6 +409,7 @@ fn compile_wooden_fish_draft_tx(
|
|||||||
published_at: None,
|
published_at: None,
|
||||||
background_asset_json: background_asset.as_ref().map(to_json_string),
|
background_asset_json: background_asset.as_ref().map(to_json_string),
|
||||||
back_button_asset_json: back_button_asset.as_ref().map(to_json_string),
|
back_button_asset_json: back_button_asset.as_ref().map(to_json_string),
|
||||||
|
visible: true,
|
||||||
};
|
};
|
||||||
upsert_work(ctx, row);
|
upsert_work(ctx, row);
|
||||||
let config = config_from_draft(&draft);
|
let config = config_from_draft(&draft);
|
||||||
@@ -1269,6 +1271,7 @@ fn clone_work(row: &WoodenFishWorkProfileRow) -> WoodenFishWorkProfileRow {
|
|||||||
play_count: row.play_count,
|
play_count: row.play_count,
|
||||||
updated_at: row.updated_at,
|
updated_at: row.updated_at,
|
||||||
published_at: row.published_at,
|
published_at: row.published_at,
|
||||||
|
visible: row.visible,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
const WORK_VISIBLE_DEFAULT: bool = true;
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
accessor = wooden_fish_agent_session,
|
accessor = wooden_fish_agent_session,
|
||||||
index(accessor = by_wooden_fish_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
index(accessor = by_wooden_fish_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
||||||
@@ -49,6 +51,9 @@ pub struct WoodenFishWorkProfileRow {
|
|||||||
pub(crate) background_asset_json: Option<String>,
|
pub(crate) background_asset_json: Option<String>,
|
||||||
#[default(None::<String>)]
|
#[default(None::<String>)]
|
||||||
pub(crate) back_button_asset_json: Option<String>,
|
pub(crate) back_button_asset_json: Option<String>,
|
||||||
|
// ???????????????????????????????
|
||||||
|
#[default(WORK_VISIBLE_DEFAULT)]
|
||||||
|
pub(crate) visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spacetimedb::table(
|
#[spacetimedb::table(
|
||||||
|
|||||||
Reference in New Issue
Block a user