use helix_core::{Effect, EffectSink};
use crate::error::ImError;
use super::super::{ImWsContext, WsFrame, WsHandlerRegistration, WsMessageHandler};
const SCHEDULE_CANCELED_ACTION: &str = "post_schedule_canceled";
struct ScheduleCanceledHandler;
impl WsMessageHandler for ScheduleCanceledHandler {
fn action(&self) -> &'static str {
SCHEDULE_CANCELED_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(fact) = crate::channel::write::ScheduleFact::from_canceled_ws(
data,
frame.event_seq().map(|seq| seq.0),
) else {
return Ok(());
};
let requested_by_viewer = ctx
.state
.pending_schedule_cancel_requests
.contains_key(&fact.channel_id);
if !requested_by_viewer
&& (fact.owner_user_id.is_empty() || fact.owner_user_id != ctx.auth_user_id)
{
return Ok(());
}
let committed = ctx
.state
.committed_schedule_revisions
.get(&fact.channel_id)
.copied()
.unwrap_or(0);
let inflight = ctx
.state
.inflight_schedule_revisions
.get(&fact.channel_id)
.copied()
.unwrap_or(0);
if fact.revision <= committed.max(inflight) {
return Ok(());
}
let channel_id = fact.channel_id;
let revision = fact.revision;
let causation_id = ctx
.state
.pending_schedule_cancel_requests
.get(&channel_id)
.cloned();
let corr = ctx.alloc_corr();
ctx.state
.inflight_schedule_revisions
.insert(channel_id, revision);
ctx.state.corr_map.insert(
corr,
crate::state::CorrelationContext::ScheduleCanceledPersist {
channel_id,
revision,
causation_id,
},
);
out.push(Effect::PersistAtomic {
corr,
ops: fact.storage_ops(),
});
Ok(())
}
}
static SCHEDULE_CANCELED_HANDLER: ScheduleCanceledHandler = ScheduleCanceledHandler;
#[cfg(target_arch = "wasm32")]
pub(super) fn inventory_link_anchor() {
std::hint::black_box(&SCHEDULE_CANCELED_HANDLER);
}
inventory::submit! {
WsHandlerRegistration {
action: SCHEDULE_CANCELED_ACTION,
handler: &SCHEDULE_CANCELED_HANDLER,
}
}