fix: polish bark battle creation flow

This commit is contained in:
kdletters
2026-05-22 05:00:07 +08:00
parent 01da85a577
commit bf82f04b64
73 changed files with 9362 additions and 2663 deletions

View File

@@ -1,4 +1,5 @@
use super::*;
use std::collections::HashMap;
pub type BarkBattleDraftCreateRecordInput = BarkBattleDraftCreateInput;
pub type BarkBattleDraftConfigUpsertRecordInput = BarkBattleDraftConfigUpsertInput;
@@ -44,6 +45,32 @@ impl SpacetimeClient {
.await
}
pub async fn get_bark_battle_draft_config(
&self,
draft_id: String,
owner_user_id: String,
) -> Result<BarkBattleDraftConfigRecord, SpacetimeClientError> {
self.read_after_connect("get_bark_battle_draft_config", move |connection| {
let row = connection
.db()
.bark_battle_draft_config()
.draft_id()
.find(&draft_id)
.ok_or_else(|| {
SpacetimeClientError::procedure_failed(Some(
"bark_battle draft 不存在".to_string(),
))
})?;
if row.owner_user_id != owner_user_id {
return Err(SpacetimeClientError::procedure_failed(Some(
"bark_battle draft owner 不匹配".to_string(),
)));
}
Ok(map_bark_battle_draft_config_row(row))
})
.await
}
pub async fn publish_bark_battle_work(
&self,
input: BarkBattleWorkPublishRecordInput,
@@ -142,4 +169,83 @@ impl SpacetimeClient {
})
.await
}
pub async fn list_bark_battle_works(
&self,
owner_user_id: String,
) -> Result<Vec<serde_json::Value>, SpacetimeClientError> {
self.read_after_connect("list_bark_battle_works", move |connection| {
let owner_user_id = owner_user_id.as_str();
let drafts: Vec<serde_json::Value> = connection
.db()
.bark_battle_draft_config()
.iter()
.filter(|row| row.owner_user_id == owner_user_id)
.map(map_bark_battle_draft_config_row)
.collect();
let published: Vec<serde_json::Value> = connection
.db()
.bark_battle_published_config()
.iter()
.filter(|row| row.owner_user_id == owner_user_id)
.map(map_bark_battle_published_config_row)
.collect();
let mut works_by_id: HashMap<String, serde_json::Value> = HashMap::new();
for work in published.into_iter().chain(drafts) {
let Some(work_id) = work
.get("workId")
.and_then(serde_json::Value::as_str)
.filter(|value| !value.trim().is_empty())
.map(ToString::to_string)
else {
continue;
};
works_by_id.entry(work_id).or_insert(work);
}
let mut works: Vec<serde_json::Value> = works_by_id.into_values().collect();
works.sort_by(|left: &serde_json::Value, right: &serde_json::Value| {
let left_updated_at = left
.get("updatedAtMicros")
.and_then(serde_json::Value::as_i64)
.unwrap_or_default();
let right_updated_at = right
.get("updatedAtMicros")
.and_then(serde_json::Value::as_i64)
.unwrap_or_default();
right_updated_at.cmp(&left_updated_at)
});
Ok(works)
})
.await
}
pub async fn list_bark_battle_gallery(
&self,
) -> Result<Vec<serde_json::Value>, SpacetimeClientError> {
self.read_after_connect("list_bark_battle_gallery", move |connection| {
let recent_play_counts = public_work_recent_play_counts(connection, "bark-battle");
let mut items = connection
.db()
.bark_battle_gallery_view()
.iter()
.collect::<Vec<_>>();
items.sort_by(|left, right| {
right
.updated_at_micros
.cmp(&left.updated_at_micros)
.then_with(|| left.work_id.cmp(&right.work_id))
});
Ok(items
.into_iter()
.map(|item| {
let recent_play_count_7d =
recent_play_counts.get(&item.work_id).copied().unwrap_or(0);
map_bark_battle_gallery_view_row(item, recent_play_count_7d)
})
.collect())
})
.await
}
}