use super::*; use std::collections::HashMap; pub type BarkBattleDraftCreateRecordInput = BarkBattleDraftCreateInput; pub type BarkBattleDraftConfigUpsertRecordInput = BarkBattleDraftConfigUpsertInput; pub type BarkBattleWorkPublishRecordInput = BarkBattleWorkPublishInput; pub type BarkBattleRunStartRecordInput = BarkBattleRunStartInput; pub type BarkBattleRunFinishRecordInput = BarkBattleRunFinishInput; impl SpacetimeClient { pub async fn create_bark_battle_draft( &self, input: BarkBattleDraftCreateRecordInput, ) -> Result { self.call_after_connect("create_bark_battle_draft", move |connection, sender| { connection .procedures() .create_bark_battle_draft_then(input, move |_, result| { let mapped = result .map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .and_then(map_bark_battle_draft_config_procedure_result); send_once(&sender, mapped); }); }) .await } pub async fn update_bark_battle_draft_config( &self, input: BarkBattleDraftConfigUpsertRecordInput, ) -> Result { self.call_after_connect( "update_bark_battle_draft_config", move |connection, sender| { connection .procedures() .update_bark_battle_draft_config_then(input, move |_, result| { let mapped = result .map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .and_then(map_bark_battle_draft_config_procedure_result); send_once(&sender, mapped); }); }, ) .await } pub async fn get_bark_battle_draft_config( &self, draft_id: String, owner_user_id: String, ) -> Result { 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, ) -> Result { self.call_after_connect("publish_bark_battle_work", move |connection, sender| { connection .procedures() .publish_bark_battle_work_then(input, move |_, result| { let mapped = result .map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .and_then(map_bark_battle_runtime_config_procedure_result); send_once(&sender, mapped); }); }) .await } pub async fn get_bark_battle_runtime_config( &self, work_id: String, owner_user_id: Option, ) -> Result { let input = BarkBattleRuntimeConfigGetInput { work_id, owner_user_id, }; self.call_after_connect( "get_bark_battle_runtime_config", move |connection, sender| { connection.procedures().get_bark_battle_runtime_config_then( input, move |_, result| { let mapped = result .map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .and_then(map_bark_battle_runtime_config_procedure_result); send_once(&sender, mapped); }, ); }, ) .await } pub async fn start_bark_battle_run( &self, input: BarkBattleRunStartRecordInput, ) -> Result { self.call_after_connect("start_bark_battle_run", move |connection, sender| { connection .procedures() .start_bark_battle_run_then(input, move |_, result| { let mapped = result .map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .and_then(map_bark_battle_run_procedure_result); send_once(&sender, mapped); }); }) .await } pub async fn finish_bark_battle_run( &self, input: BarkBattleRunFinishRecordInput, ) -> Result { self.call_after_connect("finish_bark_battle_run", move |connection, sender| { connection .procedures() .finish_bark_battle_run_then(input, move |_, result| { let mapped = result .map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .and_then(map_bark_battle_run_procedure_result); send_once(&sender, mapped); }); }) .await } pub async fn get_bark_battle_run( &self, run_id: String, owner_user_id: String, ) -> Result { let input = BarkBattleRunGetInput { run_id, owner_user_id, }; self.call_after_connect("get_bark_battle_run", move |connection, sender| { connection .procedures() .get_bark_battle_run_then(input, move |_, result| { let mapped = result .map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .and_then(map_bark_battle_run_procedure_result); send_once(&sender, mapped); }); }) .await } pub async fn list_bark_battle_works( &self, owner_user_id: String, ) -> Result, SpacetimeClientError> { self.read_after_connect("list_bark_battle_works", move |connection| { let owner_user_id = owner_user_id.as_str(); let drafts: Vec = 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 = 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 = 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 = 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, 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::>(); 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 } }