use helix_core::effect::SqlValue;
use helix_core::{Effect, EffectSink};
use crate::error::ImError;
use crate::state::ChannelId;
use super::super::{ImWsContext, WsFrame, WsHandlerRegistration, WsMessageHandler};
const CHANNEL_CLOSE_ACTION: &str = "channel_close";
struct ChannelCloseHandler;
impl WsMessageHandler for ChannelCloseHandler {
fn action(&self) -> &'static str {
CHANNEL_CLOSE_ACTION
}
fn handle(
&self,
ctx: &mut ImWsContext<'_>,
frame: &WsFrame,
out: &mut EffectSink,
) -> Result<(), ImError> {
let Ok(data) = frame.data_required() else {
return Ok(());
};
let Some(channel_id) = data
.get("channelId")
.or_else(|| data.get("channel_id"))
.and_then(serde_json::Value::as_str)
.and_then(ChannelId::from_str)
else {
return Ok(());
};
let delete_at = data
.get("deleteAt")
.or_else(|| data.get("delete_at"))
.and_then(serde_json::Value::as_i64)
.unwrap_or(0);
let is_viewer_left = data
.get("terminalReason")
.or_else(|| data.get("terminal_reason"))
.and_then(serde_json::Value::as_str)
== Some("left");
let (transition, cols) = if is_viewer_left {
(
crate::state::ChannelLifecycleTransition::Left,
vec![("is_remove", SqlValue::Integer(1))],
)
} else {
(
crate::state::ChannelLifecycleTransition::Closed { delete_at },
vec![
("delete_at", SqlValue::Integer(delete_at)),
("is_active", SqlValue::Integer(0)),
],
)
};
let corr = ctx.alloc_corr();
ctx.state.corr_map.insert(
corr,
crate::state::CorrelationContext::ChannelLifecyclePersist {
channel_id,
transition,
causation_id: None,
},
);
let mut ops = vec![crate::acl::to_effect_s1::channel_set_cols_op(
channel_id, cols,
)];
if is_viewer_left && !ctx.auth_user_id.is_empty() {
if let Some(delete_member) = crate::acl::to_effect_s1::delete_channel_members_op(
channel_id,
vec![ctx.auth_user_id.to_string()],
) {
ops.push(delete_member);
}
}
out.push(Effect::PersistAtomic { corr, ops });
Ok(())
}
}
static CHANNEL_CLOSE_HANDLER: ChannelCloseHandler = ChannelCloseHandler;
#[cfg(target_arch = "wasm32")]
pub(super) fn inventory_link_anchor() {
std::hint::black_box(&CHANNEL_CLOSE_HANDLER);
}
inventory::submit! {
WsHandlerRegistration {
action: CHANNEL_CLOSE_ACTION,
handler: &CHANNEL_CLOSE_HANDLER,
}
}