Destroy invitation message after accepting invitation
This commit is contained in:
parent
d3b2fbce32
commit
9b6bfc76cb
@ -113,13 +113,13 @@ nav#sidebar .linkItem > a > .linkText {
|
|||||||
|
|
||||||
.styledTooltip.messages > .messagesList > .message {
|
.styledTooltip.messages > .messagesList > .message {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
max-height: 90px;
|
/*max-height: 90px;*/
|
||||||
overflow: hidden;
|
/*overflow: hidden;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.styledTooltip.messages > .messagesList > .message:hover {
|
/*.styledTooltip.messages > .messagesList > .message:hover {*/
|
||||||
max-height: 100%;
|
/* max-height: 100%;*/
|
||||||
}
|
/*}*/
|
||||||
|
|
||||||
.styledTooltip.messages > .messagesList > .message > .top {
|
.styledTooltip.messages > .messagesList > .message > .top {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -213,8 +213,21 @@ pub fn update(msg: &WsMsg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// messages
|
// messages
|
||||||
|
WsMsg::Message(received) => {
|
||||||
|
let mut old = vec![];
|
||||||
|
std::mem::swap(&mut old, &mut model.messages);
|
||||||
|
for m in old {
|
||||||
|
if m.id != received.id {
|
||||||
|
model.messages.push(m);
|
||||||
|
} else {
|
||||||
|
model.messages.push(received.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.messages.sort_by(|a, b| a.id.cmp(&b.id));
|
||||||
|
}
|
||||||
WsMsg::MessagesResponse(v) => {
|
WsMsg::MessagesResponse(v) => {
|
||||||
model.messages = v.clone();
|
model.messages = v.clone();
|
||||||
|
model.messages.sort_by(|a, b| a.id.cmp(&b.id));
|
||||||
}
|
}
|
||||||
WsMsg::MessageMarkedSeen(id) => {
|
WsMsg::MessageMarkedSeen(id) => {
|
||||||
let mut old = vec![];
|
let mut old = vec![];
|
||||||
@ -224,6 +237,7 @@ pub fn update(msg: &WsMsg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
|||||||
model.messages.push(m);
|
model.messages.push(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
model.messages.sort_by(|a, b| a.id.cmp(&b.id));
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ use jirs_data::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::db::tokens::CreateBindToken;
|
use crate::db::tokens::CreateBindToken;
|
||||||
use crate::db::users::{FindUser, Register};
|
use crate::db::users::{LookupUser, Register};
|
||||||
use crate::db::DbExecutor;
|
use crate::db::DbExecutor;
|
||||||
use crate::errors::ServiceErrors;
|
use crate::errors::ServiceErrors;
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ impl Handler<AcceptInvitation> for DbExecutor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let user: User = self.handle(
|
let user: User = self.handle(
|
||||||
FindUser {
|
LookupUser {
|
||||||
name: invitation.name.clone(),
|
name: invitation.name.clone(),
|
||||||
email: invitation.email.clone(),
|
email: invitation.email.clone(),
|
||||||
},
|
},
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use actix::Handler;
|
use actix::Handler;
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
|
|
||||||
use jirs_data::{Message, MessageId, UserId};
|
use jirs_data::{BindToken, Message, MessageId, MessageType, User, UserId};
|
||||||
|
|
||||||
|
use crate::db::users::{FindUser, LookupUser};
|
||||||
use crate::db::DbExecutor;
|
use crate::db::DbExecutor;
|
||||||
use crate::errors::ServiceErrors;
|
use crate::errors::ServiceErrors;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct LoadMessages {
|
pub struct LoadMessages {
|
||||||
pub user_id: UserId,
|
pub user_id: UserId,
|
||||||
}
|
}
|
||||||
@ -36,6 +38,7 @@ impl Handler<LoadMessages> for DbExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct MarkMessageSeen {
|
pub struct MarkMessageSeen {
|
||||||
pub user_id: UserId,
|
pub user_id: UserId,
|
||||||
pub message_id: MessageId,
|
pub message_id: MessageId,
|
||||||
@ -61,13 +64,119 @@ impl Handler<MarkMessageSeen> for DbExecutor {
|
|||||||
.find(msg.message_id)
|
.find(msg.message_id)
|
||||||
.filter(receiver_id.eq(msg.user_id)),
|
.filter(receiver_id.eq(msg.user_id)),
|
||||||
);
|
);
|
||||||
|
debug!("{}", diesel::debug_query::<diesel::pg::Pg, _>(&query));
|
||||||
|
let size = query
|
||||||
|
.execute(conn)
|
||||||
|
.map_err(|_| ServiceErrors::DatabaseQueryFailed("load user messages".to_string()))?;
|
||||||
|
|
||||||
|
if size > 0 {
|
||||||
|
Ok(msg.message_id)
|
||||||
|
} else {
|
||||||
|
Err(ServiceErrors::DatabaseQueryFailed(format!(
|
||||||
|
"failed to delete message for {:?}",
|
||||||
|
msg
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum CreateMessageReceiver {
|
||||||
|
Reference(UserId),
|
||||||
|
Lookup { name: String, email: String },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CreateMessage {
|
||||||
|
pub receiver: CreateMessageReceiver,
|
||||||
|
pub sender_id: UserId,
|
||||||
|
pub summary: String,
|
||||||
|
pub description: String,
|
||||||
|
pub message_type: MessageType,
|
||||||
|
pub hyper_link: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl actix::Message for CreateMessage {
|
||||||
|
type Result = Result<Message, ServiceErrors>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Handler<CreateMessage> for DbExecutor {
|
||||||
|
type Result = Result<Message, ServiceErrors>;
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: CreateMessage, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
use crate::schema::messages::dsl::*;
|
||||||
|
|
||||||
|
let conn = &self
|
||||||
|
.pool
|
||||||
|
.get()
|
||||||
|
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
||||||
|
|
||||||
|
let user: User = match {
|
||||||
|
match msg.receiver {
|
||||||
|
CreateMessageReceiver::Lookup { name, email } => {
|
||||||
|
self.handle(LookupUser { name, email }, ctx)
|
||||||
|
}
|
||||||
|
CreateMessageReceiver::Reference(user_id) => self.handle(FindUser { user_id }, ctx),
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
Ok(user) => user,
|
||||||
|
_ => {
|
||||||
|
return Err(ServiceErrors::RecordNotFound(
|
||||||
|
"No matching user found".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let query = diesel::insert_into(messages).values((
|
||||||
|
receiver_id.eq(user.id),
|
||||||
|
sender_id.eq(msg.sender_id),
|
||||||
|
summary.eq(msg.summary),
|
||||||
|
description.eq(msg.description),
|
||||||
|
message_type.eq(msg.message_type),
|
||||||
|
hyper_link.eq(msg.hyper_link),
|
||||||
|
));
|
||||||
debug!(
|
debug!(
|
||||||
"{}",
|
"{}",
|
||||||
diesel::debug_query::<diesel::pg::Pg, _>(&query).to_string()
|
diesel::debug_query::<diesel::pg::Pg, _>(&query).to_string()
|
||||||
);
|
);
|
||||||
query
|
query
|
||||||
.execute(conn)
|
.get_result(conn)
|
||||||
.map_err(|_| ServiceErrors::DatabaseQueryFailed("load user messages".to_string()))?;
|
.map_err(|_| ServiceErrors::DatabaseQueryFailed("create message failed".to_string()))
|
||||||
Ok(msg.message_id)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct LookupMessagesByToken {
|
||||||
|
pub token: BindToken,
|
||||||
|
pub user_id: UserId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl actix::Message for LookupMessagesByToken {
|
||||||
|
type Result = Result<Vec<Message>, ServiceErrors>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Handler<LookupMessagesByToken> for DbExecutor {
|
||||||
|
type Result = Result<Vec<Message>, ServiceErrors>;
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: LookupMessagesByToken, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
use crate::schema::messages::dsl::*;
|
||||||
|
|
||||||
|
let conn = &self
|
||||||
|
.pool
|
||||||
|
.get()
|
||||||
|
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
||||||
|
|
||||||
|
let query = messages.filter(
|
||||||
|
hyper_link
|
||||||
|
.eq(format!("#{}", msg.token))
|
||||||
|
.and(receiver_id.eq(msg.user_id)),
|
||||||
|
);
|
||||||
|
debug!(
|
||||||
|
"{}",
|
||||||
|
diesel::debug_query::<diesel::pg::Pg, _>(&query).to_string()
|
||||||
|
);
|
||||||
|
query
|
||||||
|
.load(conn)
|
||||||
|
.map_err(|_| ServiceErrors::DatabaseQueryFailed("create message failed".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use actix::{Handler, Message};
|
use actix::{Handler, Message};
|
||||||
|
use diesel::connection::TransactionManager;
|
||||||
use diesel::pg::Pg;
|
use diesel::pg::Pg;
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -9,12 +10,10 @@ use crate::db::projects::CreateProject;
|
|||||||
use crate::db::{DbExecutor, DbPooledConn};
|
use crate::db::{DbExecutor, DbPooledConn};
|
||||||
use crate::errors::ServiceErrors;
|
use crate::errors::ServiceErrors;
|
||||||
use crate::schema::users::all_columns;
|
use crate::schema::users::all_columns;
|
||||||
use diesel::connection::TransactionManager;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FindUser {
|
pub struct FindUser {
|
||||||
pub name: String,
|
pub user_id: UserId,
|
||||||
pub email: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message for FindUser {
|
impl Message for FindUser {
|
||||||
@ -27,6 +26,35 @@ impl Handler<FindUser> for DbExecutor {
|
|||||||
fn handle(&mut self, msg: FindUser, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: FindUser, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
use crate::schema::users::dsl::*;
|
use crate::schema::users::dsl::*;
|
||||||
|
|
||||||
|
let conn = &self
|
||||||
|
.pool
|
||||||
|
.get()
|
||||||
|
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
||||||
|
|
||||||
|
let query = users.find(msg.user_id);
|
||||||
|
debug!("{}", diesel::debug_query::<Pg, _>(&query));
|
||||||
|
query
|
||||||
|
.first(conn)
|
||||||
|
.map_err(|_| ServiceErrors::RecordNotFound(format!("user with id = {}", msg.user_id)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct LookupUser {
|
||||||
|
pub name: String,
|
||||||
|
pub email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Message for LookupUser {
|
||||||
|
type Result = Result<User, ServiceErrors>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Handler<LookupUser> for DbExecutor {
|
||||||
|
type Result = Result<User, ServiceErrors>;
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: LookupUser, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
use crate::schema::users::dsl::*;
|
||||||
|
|
||||||
let conn = &self
|
let conn = &self
|
||||||
.pool
|
.pool
|
||||||
.get()
|
.get()
|
||||||
@ -43,7 +71,7 @@ impl Handler<FindUser> for DbExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug)]
|
||||||
pub struct LoadProjectUsers {
|
pub struct LoadProjectUsers {
|
||||||
pub project_id: i32,
|
pub project_id: i32,
|
||||||
}
|
}
|
||||||
@ -76,7 +104,7 @@ impl Handler<LoadProjectUsers> for DbExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug)]
|
||||||
pub struct LoadIssueAssignees {
|
pub struct LoadIssueAssignees {
|
||||||
pub issue_id: i32,
|
pub issue_id: i32,
|
||||||
}
|
}
|
||||||
@ -109,7 +137,7 @@ impl Handler<LoadIssueAssignees> for DbExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Register {
|
pub struct Register {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub email: String,
|
pub email: String,
|
||||||
@ -309,11 +337,13 @@ impl Handler<ProfileUpdate> for DbExecutor {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use diesel::connection::TransactionManager;
|
||||||
|
|
||||||
|
use jirs_data::{Project, ProjectCategory};
|
||||||
|
|
||||||
use crate::db::build_pool;
|
use crate::db::build_pool;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use diesel::connection::TransactionManager;
|
|
||||||
use jirs_data::{Project, ProjectCategory};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_collision() {
|
fn check_collision() {
|
||||||
|
@ -5,7 +5,7 @@ use jirs_data::{Token, WsMsg};
|
|||||||
|
|
||||||
use crate::db::authorize_user::AuthorizeUser;
|
use crate::db::authorize_user::AuthorizeUser;
|
||||||
use crate::db::tokens::{CreateBindToken, FindBindToken};
|
use crate::db::tokens::{CreateBindToken, FindBindToken};
|
||||||
use crate::db::users::FindUser;
|
use crate::db::users::LookupUser;
|
||||||
use crate::mail::welcome::Welcome;
|
use crate::mail::welcome::Welcome;
|
||||||
use crate::ws::{WebSocketActor, WsHandler, WsResult};
|
use crate::ws::{WebSocketActor, WsHandler, WsResult};
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ impl WsHandler<Authenticate> for WebSocketActor {
|
|||||||
fn handle_msg(&mut self, msg: Authenticate, _ctx: &mut Self::Context) -> WsResult {
|
fn handle_msg(&mut self, msg: Authenticate, _ctx: &mut Self::Context) -> WsResult {
|
||||||
let Authenticate { name, email } = msg;
|
let Authenticate { name, email } = msg;
|
||||||
// TODO check attempt number, allow only 5 times per day
|
// TODO check attempt number, allow only 5 times per day
|
||||||
let user = match block_on(self.db.send(FindUser { name, email })) {
|
let user = match block_on(self.db.send(LookupUser { name, email })) {
|
||||||
Ok(Ok(user)) => user,
|
Ok(Ok(user)) => user,
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
|
|
||||||
use jirs_data::{EmailString, InvitationId, InvitationToken, UserRole, UsernameString, WsMsg};
|
use jirs_data::{
|
||||||
|
EmailString, InvitationId, InvitationToken, MessageType, UserRole, UsernameString, WsMsg,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::db::invitations;
|
use crate::db::invitations;
|
||||||
use crate::ws::{WebSocketActor, WsHandler, WsResult};
|
use crate::db::messages::CreateMessageReceiver;
|
||||||
|
use crate::ws::{InnerMsg, WebSocketActor, WsHandler, WsMessageSender, WsResult};
|
||||||
|
|
||||||
pub struct ListInvitation;
|
pub struct ListInvitation;
|
||||||
|
|
||||||
@ -40,18 +43,14 @@ impl WsHandler<CreateInvitation> for WebSocketActor {
|
|||||||
Some(up) => up.project_id,
|
Some(up) => up.project_id,
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
let (user_id, inviter_name) =
|
let (user_id, inviter_name) = self.require_user().map(|u| (u.id, u.name.clone()))?;
|
||||||
match self.current_user.as_ref().map(|u| (u.id, u.name.clone())) {
|
|
||||||
Some(id) => id,
|
|
||||||
_ => return Ok(None),
|
|
||||||
};
|
|
||||||
|
|
||||||
let CreateInvitation { email, name, role } = msg;
|
let CreateInvitation { email, name, role } = msg;
|
||||||
let invitation = match block_on(self.db.send(invitations::CreateInvitation {
|
let invitation = match block_on(self.db.send(crate::db::invitations::CreateInvitation {
|
||||||
user_id,
|
user_id,
|
||||||
project_id,
|
project_id,
|
||||||
email,
|
email: email.clone(),
|
||||||
name,
|
name: name.clone(),
|
||||||
role,
|
role,
|
||||||
})) {
|
})) {
|
||||||
Ok(Ok(invitation)) => invitation,
|
Ok(Ok(invitation)) => invitation,
|
||||||
@ -80,6 +79,24 @@ impl WsHandler<CreateInvitation> for WebSocketActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If user exists then send message to him
|
||||||
|
match block_on(self.db.send(crate::db::messages::CreateMessage {
|
||||||
|
receiver: CreateMessageReceiver::Lookup { name, email },
|
||||||
|
sender_id: user_id,
|
||||||
|
summary: "You have been invited to project".to_string(),
|
||||||
|
description: "You have been invited to project".to_string(),
|
||||||
|
message_type: MessageType::ReceivedInvitation,
|
||||||
|
hyper_link: format!("#{}", invitation.bind_token),
|
||||||
|
})) {
|
||||||
|
Ok(Ok(message)) => {
|
||||||
|
self.addr.do_send(InnerMsg::SendToUser(
|
||||||
|
message.receiver_id,
|
||||||
|
WsMsg::Message(message),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Some(WsMsg::InvitationSendSuccess))
|
Ok(Some(WsMsg::InvitationSendSuccess))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,21 +152,45 @@ pub struct AcceptInvitation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WsHandler<AcceptInvitation> for WebSocketActor {
|
impl WsHandler<AcceptInvitation> for WebSocketActor {
|
||||||
fn handle_msg(&mut self, msg: AcceptInvitation, _ctx: &mut Self::Context) -> WsResult {
|
fn handle_msg(&mut self, msg: AcceptInvitation, ctx: &mut Self::Context) -> WsResult {
|
||||||
let AcceptInvitation { invitation_token } = msg;
|
let AcceptInvitation { invitation_token } = msg;
|
||||||
let res = match block_on(self.db.send(invitations::AcceptInvitation {
|
let token = match block_on(self.db.send(invitations::AcceptInvitation {
|
||||||
invitation_token: invitation_token.clone(),
|
invitation_token: invitation_token.clone(),
|
||||||
})) {
|
})) {
|
||||||
Ok(Ok(token)) => Some(WsMsg::InvitationAcceptSuccess(token.access_token)),
|
Ok(Ok(token)) => token,
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
Some(WsMsg::InvitationAcceptFailure(invitation_token))
|
return Ok(Some(WsMsg::InvitationAcceptFailure(invitation_token)));
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("{}", e);
|
error!("{}", e);
|
||||||
Some(WsMsg::InvitationAcceptFailure(invitation_token))
|
return Ok(Some(WsMsg::InvitationAcceptFailure(invitation_token)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(res)
|
|
||||||
|
for message in block_on(self.db.send(crate::db::messages::LookupMessagesByToken {
|
||||||
|
token: invitation_token,
|
||||||
|
user_id: token.user_id,
|
||||||
|
}))
|
||||||
|
.unwrap_or(Ok(vec![]))
|
||||||
|
.unwrap_or_default()
|
||||||
|
{
|
||||||
|
match block_on(self.db.send(crate::db::messages::MarkMessageSeen {
|
||||||
|
user_id: token.user_id,
|
||||||
|
message_id: message.id,
|
||||||
|
})) {
|
||||||
|
Ok(Ok(id)) => {
|
||||||
|
ctx.send_msg(&WsMsg::MessageMarkedSeen(id));
|
||||||
|
}
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
error!("{:?}", e);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Some(WsMsg::InvitationAcceptSuccess(token.access_token)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,6 +325,7 @@ pub enum InnerMsg {
|
|||||||
Join(ProjectId, UserId, Recipient<InnerMsg>),
|
Join(ProjectId, UserId, Recipient<InnerMsg>),
|
||||||
Leave(ProjectId, UserId, Recipient<InnerMsg>),
|
Leave(ProjectId, UserId, Recipient<InnerMsg>),
|
||||||
BroadcastToChannel(ProjectId, WsMsg),
|
BroadcastToChannel(ProjectId, WsMsg),
|
||||||
|
SendToUser(UserId, WsMsg),
|
||||||
Transfer(WsMsg),
|
Transfer(WsMsg),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,13 +382,17 @@ impl Handler<InnerMsg> for WsServer {
|
|||||||
v.remove_item(&recipient);
|
v.remove_item(&recipient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
InnerMsg::SendToUser(user_id, msg) => {
|
||||||
|
if let Some(v) = self.sessions.get(&user_id) {
|
||||||
|
self.send_to_recipients(v, &msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
InnerMsg::BroadcastToChannel(project_id, msg) => {
|
InnerMsg::BroadcastToChannel(project_id, msg) => {
|
||||||
debug!("Begin broadcast to channel {} msg {:?}", project_id, msg);
|
debug!("Begin broadcast to channel {} msg {:?}", project_id, msg);
|
||||||
let set = match self.rooms.get(&project_id) {
|
let set = match self.rooms.get(&project_id) {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
_ => return debug!(" channel not found, aborting..."),
|
_ => return debug!(" channel not found, aborting..."),
|
||||||
};
|
};
|
||||||
let _s = set.len();
|
|
||||||
for r in set.keys() {
|
for r in set.keys() {
|
||||||
let v = match self.sessions.get(r) {
|
let v = match self.sessions.get(r) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
@ -396,12 +401,7 @@ impl Handler<InnerMsg> for WsServer {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for recipient in v.iter() {
|
self.send_to_recipients(v, &msg);
|
||||||
match recipient.do_send(InnerMsg::Transfer(msg.clone())) {
|
|
||||||
Ok(_) => debug!("msg sent"),
|
|
||||||
Err(e) => error!("{}", e),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -413,6 +413,15 @@ impl WsServer {
|
|||||||
pub fn ensure_room(&mut self, room: i32) {
|
pub fn ensure_room(&mut self, room: i32) {
|
||||||
self.rooms.entry(room).or_insert_with(HashMap::new);
|
self.rooms.entry(room).or_insert_with(HashMap::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_to_recipients(&self, recipients: &Vec<Recipient<InnerMsg>>, msg: &WsMsg) {
|
||||||
|
for recipient in recipients.iter() {
|
||||||
|
match recipient.do_send(InnerMsg::Transfer(msg.clone())) {
|
||||||
|
Ok(_) => debug!("msg sent"),
|
||||||
|
Err(e) => error!("{}", e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/ws/")]
|
#[get("/ws/")]
|
||||||
|
Loading…
Reference in New Issue
Block a user