feat: add visible flag for works

This commit is contained in:
kdletters
2026-05-27 19:30:10 +08:00
parent a7bba70ca5
commit 8e96c8a67c
29 changed files with 198 additions and 12 deletions

View File

@@ -2,6 +2,8 @@ use crate::*;
use spacetimedb::AnonymousViewContext;
use std::collections::{HashMap, HashSet};
const WORK_VISIBLE_DEFAULT: bool = true;
#[spacetimedb::table(
accessor = custom_world_profile,
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>,
created_at: Timestamp,
updated_at: Timestamp,
// ??????????????????????????
#[default(WORK_VISIBLE_DEFAULT)]
visible: bool,
}
#[spacetimedb::table(
@@ -192,6 +197,9 @@ pub struct CustomWorldGalleryEntry {
like_count: u32,
published_at: Timestamp,
updated_at: Timestamp,
// ??????????????????????????
#[default(WORK_VISIBLE_DEFAULT)]
visible: bool,
}
// Agent 会话首版只负责把可持久化创作状态落进 SpacetimeDBLLM 采集与卡片生成后续再接入。
#[spacetimedb::procedure]
@@ -1229,6 +1237,7 @@ fn upsert_custom_world_profile_record(
deleted_at: None,
created_at: existing.created_at,
updated_at,
visible: existing.visible,
}
}
None => CustomWorldProfile {
@@ -1254,6 +1263,7 @@ fn upsert_custom_world_profile_record(
deleted_at: None,
created_at: updated_at,
updated_at,
visible: true,
},
};
@@ -1401,6 +1411,7 @@ fn publish_custom_world_profile_record(
deleted_at: None,
created_at: existing.created_at,
updated_at: published_at,
visible: existing.visible,
};
let inserted = ctx.db.custom_world_profile().insert(next_row);
@@ -1467,6 +1478,7 @@ fn unpublish_custom_world_profile_record(
deleted_at: None,
created_at: existing.created_at,
updated_at,
visible: existing.visible,
};
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),
created_at: existing.created_at,
updated_at: deleted_at,
visible: existing.visible,
};
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.publication_status == CustomWorldPublicationStatus::Published
&& row.deleted_at.is_none()
&& row.visible
});
let gallery_entry = ctx
@@ -1745,6 +1759,7 @@ fn remix_custom_world_profile_record(
.filter(|row| {
row.publication_status == CustomWorldPublicationStatus::Published
&& row.deleted_at.is_none()
&& row.visible
&& row.published_at.is_some()
})
.ok_or_else(|| "custom_world 已发布源作品不存在,无法改编".to_string())?;
@@ -1777,6 +1792,7 @@ fn remix_custom_world_profile_record(
deleted_at: source.deleted_at,
created_at: source.created_at,
updated_at: remixed_at,
visible: source.visible,
};
let updated_source = ctx.db.custom_world_profile().insert(next_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,
created_at: remixed_at,
updated_at: remixed_at,
visible: true,
};
if let Some(existing_target) = ctx
@@ -1845,6 +1862,7 @@ fn record_custom_world_profile_play_record(
.filter(|row| {
row.publication_status == CustomWorldPublicationStatus::Published
&& row.deleted_at.is_none()
&& row.visible
&& row.published_at.is_some()
})
.ok_or_else(|| "custom_world 已发布作品不存在,无法记录游玩".to_string())?;
@@ -1887,6 +1905,7 @@ fn record_custom_world_profile_play_record(
deleted_at: existing.deleted_at,
created_at: existing.created_at,
updated_at: played_at,
visible: existing.visible,
};
let inserted = ctx.db.custom_world_profile().insert(next_row);
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| {
row.publication_status == CustomWorldPublicationStatus::Published
&& row.deleted_at.is_none()
&& row.visible
&& row.published_at.is_some()
})
.ok_or_else(|| "custom_world 已发布作品不存在,无法点赞".to_string())?;
@@ -1967,6 +1987,7 @@ fn record_custom_world_profile_like_record(
deleted_at: existing.deleted_at,
created_at: existing.created_at,
updated_at: liked_at,
visible: existing.visible,
};
let inserted = ctx.db.custom_world_profile().insert(next_row);
let gallery_entry = sync_custom_world_gallery_entry_from_profile(ctx, &inserted)?;
@@ -2582,6 +2603,7 @@ fn is_same_agent_draft_profile_candidate(
) -> bool {
row.owner_user_id == owner_user_id
&& row.deleted_at.is_none()
&& row.visible
&& row.publication_status == CustomWorldPublicationStatus::Draft
&& 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,
published_at,
updated_at: profile.updated_at,
visible: profile.visible,
};
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()
.by_custom_world_profile_publication_status()
.filter(CustomWorldPublicationStatus::Published)
.filter(|profile| profile.deleted_at.is_none())
.filter(|profile| profile.deleted_at.is_none() && profile.visible)
.collect::<Vec<_>>();
for profile in published_profiles {
@@ -4926,6 +4949,7 @@ fn ensure_custom_world_profile_public_fields(
deleted_at: profile.deleted_at,
created_at: profile.created_at,
updated_at: profile.updated_at,
visible: profile.visible,
};
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,
created_at: profile.created_at,
updated_at: profile.updated_at,
visible: profile.visible,
}
}
@@ -4997,7 +5022,7 @@ pub(crate) fn custom_world_public_profile_snapshots(
.custom_world_profile()
.by_custom_world_profile_publication_status()
.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))
.collect::<Vec<_>>();
@@ -5156,6 +5181,7 @@ pub(crate) fn custom_world_public_gallery_snapshots(
.custom_world_gallery_entry()
.by_custom_world_gallery_owner_user_id()
.filter(""..)
.filter(|row| row.visible)
.map(|row| {
build_custom_world_gallery_entry_snapshot_with_recent_counts(&row, &HashMap::new())
})
@@ -5377,6 +5403,7 @@ mod tests {
deleted_at: None,
created_at: Timestamp::from_micros_since_unix_epoch(1),
updated_at: Timestamp::from_micros_since_unix_epoch(1),
visible: true,
};
let deleted = CustomWorldProfile {
profile_id: "profile-1".to_string(),
@@ -5401,6 +5428,7 @@ mod tests {
deleted_at: Some(Timestamp::from_micros_since_unix_epoch(2)),
created_at: Timestamp::from_micros_since_unix_epoch(1),
updated_at: Timestamp::from_micros_since_unix_epoch(1),
visible: true,
};
let published = CustomWorldProfile {
profile_id: "profile-1".to_string(),
@@ -5425,6 +5453,7 @@ mod tests {
deleted_at: None,
created_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(
@@ -5552,6 +5581,7 @@ mod tests {
deleted_at: None,
created_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();