use crate::state::ChannelId;
use bytes::Bytes;
use helix_core::effect::DomainEventBytes;
use helix_core::Effect;
mod data;
use data::message_item_data;
pub fn emit_post_received(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
) -> Effect {
emit_post_received_for_viewer(channel_id, event_seq, msg_id, fields, "")
}
pub fn emit_post_received_for_viewer(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
viewer_user_id: &str,
) -> Effect {
use serde_json::json;
let payload = json!({
"event": "im:post:received",
"data": message_item_data(channel_id, event_seq, msg_id, fields, viewer_user_id, false),
});
let bytes = Bytes::from(
serde_json::to_vec(&payload)
.expect("emit_post_received: static JSON shape must not fail to serialize"),
);
Effect::Emit {
event: DomainEventBytes(bytes),
}
}
pub fn emit_post_read(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
) -> Effect {
emit_post_read_for_viewer(channel_id, event_seq, msg_id, fields, "")
}
pub fn emit_post_read_for_viewer(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
viewer_user_id: &str,
) -> Effect {
emit_post_read_with_receipt_revision_for_viewer(
channel_id,
event_seq,
msg_id,
fields,
0,
viewer_user_id,
)
}
pub fn emit_post_read_with_receipt_revision(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
receipt_revision: i64,
) -> Effect {
emit_post_read_with_receipt_revision_for_viewer(
channel_id,
event_seq,
msg_id,
fields,
receipt_revision,
"",
)
}
pub fn emit_post_read_with_receipt_revision_for_viewer(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
receipt_revision: i64,
viewer_user_id: &str,
) -> Effect {
use serde_json::json;
let mut data = message_item_data(channel_id, event_seq, msg_id, fields, viewer_user_id, false);
data["receiptRevision"] = json!(receipt_revision);
let payload = json!({
"event": "im:post:read",
"data": data,
});
let bytes = Bytes::from(
serde_json::to_vec(&payload)
.expect("emit_post_read: static JSON shape must not fail to serialize"),
);
Effect::Emit {
event: DomainEventBytes(bytes),
}
}
pub fn emit_sync_post_read(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
reader_id: &str,
receipt_revision: i64,
) -> Effect {
emit_sync_post_read_for_viewer(
channel_id,
event_seq,
msg_id,
fields,
reader_id,
receipt_revision,
"",
)
}
pub fn emit_sync_post_read_for_viewer(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
reader_id: &str,
receipt_revision: i64,
viewer_user_id: &str,
) -> Effect {
use serde_json::json;
let mut data = message_item_data(channel_id, event_seq, msg_id, fields, viewer_user_id, false);
data["postId"] = json!(msg_id);
data["readerId"] = json!(reader_id);
data["receiptRevision"] = json!(receipt_revision);
let payload = json!({
"event": "im:post:read",
"data": data,
});
let bytes = Bytes::from(
serde_json::to_vec(&payload)
.expect("emit_sync_post_read: static JSON shape must not fail to serialize"),
);
Effect::Emit {
event: DomainEventBytes(bytes),
}
}
pub fn emit_channel_read_echo(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
) -> Effect {
emit_channel_read_echo_for_viewer(channel_id, event_seq, msg_id, fields, "")
}
pub fn emit_channel_read_echo_for_viewer(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
viewer_user_id: &str,
) -> Effect {
use serde_json::json;
let payload = json!({
"event": "im:channel:read_echo",
"data": message_item_data(channel_id, event_seq, msg_id, fields, viewer_user_id, false),
});
let bytes = Bytes::from(
serde_json::to_vec(&payload)
.expect("emit_channel_read_echo: static JSON shape must not fail to serialize"),
);
Effect::Emit {
event: DomainEventBytes(bytes),
}
}
pub fn emit_post_updated(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
) -> Effect {
emit_post_updated_for_viewer(channel_id, event_seq, msg_id, fields, "")
}
pub fn emit_post_updated_for_viewer(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
viewer_user_id: &str,
) -> Effect {
use serde_json::json;
let payload = json!({
"event": "im:post:updated",
"data": message_item_data(channel_id, event_seq, msg_id, fields, viewer_user_id, false),
});
let bytes = Bytes::from(
serde_json::to_vec(&payload)
.expect("emit_post_updated: static JSON shape must not fail to serialize"),
);
Effect::Emit {
event: DomainEventBytes(bytes),
}
}
pub fn emit_post_deleted(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
) -> Effect {
emit_post_deleted_for_viewer(channel_id, event_seq, msg_id, fields, "", "", 0, "")
}
#[allow(clippy::too_many_arguments)]
pub fn emit_post_deleted_for_viewer(
channel_id: ChannelId,
event_seq: u64,
msg_id: &str,
fields: &crate::sync_session::PostFields,
event_id: &str,
actor_id: &str,
occurred_at: i64,
viewer_user_id: &str,
) -> Effect {
use serde_json::json;
let actor_available = !actor_id.is_empty();
let is_self = actor_available && actor_id == viewer_user_id;
let display_text = if is_self {
"你撤回了一条消息"
} else {
"某人撤回了一条消息"
};
let stable_event_id = if event_id.starts_with("revoke:") {
event_id.to_string()
} else {
format!("revoke:{}:{}", channel_id.as_str(), event_seq)
};
let mut data = message_item_data(channel_id, event_seq, msg_id, fields, "", true);
let object = data
.as_object_mut()
.expect("recall projection starts from a static JSON object");
object.insert("recalledText".to_string(), json!(fields.message));
object.insert("type".to_string(), json!("system"));
object.insert("message".to_string(), json!(display_text));
object.insert("text".to_string(), json!(display_text));
object.insert("systemNotice".to_string(), json!(true));
object.insert("isSelf".to_string(), json!(is_self));
object.insert("kind".to_string(), json!("system"));
object.insert("system".to_string(), json!(true));
object.insert("systemEvent".to_string(), json!("message-recalled"));
object.insert("eventId".to_string(), json!(stable_event_id));
object.insert("actorId".to_string(), json!(actor_id));
object.insert("actorAvailable".to_string(), json!(actor_available));
object.insert("subjectMemberIds".to_string(), json!([]));
object.insert("occurredAt".to_string(), json!(occurred_at.max(0)));
object.insert("displayText".to_string(), json!(display_text));
object.insert("previewText".to_string(), json!(display_text));
object.insert("recalledMsgId".to_string(), json!(msg_id));
object.insert("targetMsgId".to_string(), json!(msg_id));
let payload = json!({
"event": "im:post:deleted",
"data": data,
});
let bytes = Bytes::from(
serde_json::to_vec(&payload)
.expect("emit_post_deleted: static JSON shape must not fail to serialize"),
);
Effect::Emit {
event: DomainEventBytes(bytes),
}
}