Almost done, only image left

This commit is contained in:
Piyush मिश्रः 2021-02-20 13:54:52 +05:30
parent e03a51dc23
commit 6a26ff18aa
7 changed files with 580 additions and 288 deletions

View File

@ -4,15 +4,14 @@ use std::{collections::HashMap, vec};
use actix::prelude::*; use actix::prelude::*;
use actix_broker::BrokerSubscribe; use actix_broker::BrokerSubscribe;
use vecmap::VecMap; use ms::Resp;
use crate::{errors, ws_sansad, messages as ms}; use crate::{ws_sansad, messages as ms};
#[allow(dead_code)] #[allow(dead_code)]
pub struct ChatPinnd { pub struct ChatPinnd {
grih: HashMap<String, Grih>, // kunjika, Grih grih: HashMap<String, Grih>, // kunjika, Grih
vyaktigat_waitlist: Vec<VyaktiWatchlist>, vyaktigat_waitlist: Vec<VyaktiWatchlist>,
non_connected_vyakti: VecMap<String, Vyakti>, // kunjika, vayakti
} }
pub struct Grih { pub struct Grih {
@ -24,7 +23,7 @@ pub struct Loog {
addr: Addr<ws_sansad::WsSansad>, addr: Addr<ws_sansad::WsSansad>,
kunjika: String, kunjika: String,
name: String, name: String,
_tags: Vec<String> tags: Option<Vec<String>>
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -34,6 +33,8 @@ pub struct Vyakti {
} }
pub struct VyaktiWatchlist { pub struct VyaktiWatchlist {
kunjika: String, kunjika: String,
name: String,
tags: Vec<String>,
addr: Addr<ws_sansad::WsSansad> addr: Addr<ws_sansad::WsSansad>
} }
@ -43,87 +44,65 @@ impl Actor for ChatPinnd {
fn started(&mut self, ctx: &mut Self::Context) { fn started(&mut self, ctx: &mut Self::Context) {
// for actix broker // for actix broker
self.subscribe_system_async::<ms::SendText>(ctx); self.subscribe_system_async::<ms::SendText>(ctx);
self.subscribe_system_async::<ms::SendStatus>(ctx);
self.subscribe_system_async::<ms::LeaveUser>(ctx); self.subscribe_system_async::<ms::LeaveUser>(ctx);
} }
} }
// Set information of user
impl Handler<ms::SetInfoVyakti> for ChatPinnd {
type Result = Option<String>;
fn handle(&mut self, msg: ms::SetInfoVyakti, _: &mut Self::Context) -> Self::Result {
// check if vayakti info is not modified and do key exist
if !msg.modify {
if self.non_connected_vyakti.key_exist(&msg.kunjika) {
return Some("Kunjika Exists".to_owned());
}
if let Some(_) = self.grih.iter().position(|a| {
match a.1.loog.iter().position(|b| {
b.kunjika == msg.kunjika
}) {
Some(_) => true,
None => false
}
}) {
return Some("Kunjika Exists".to_owned());
}
}
// change value
self.non_connected_vyakti.insert(msg.kunjika, Vyakti {
name: msg.name,
tags: msg.tags
});
None
}
}
/// Join grih /// Join grih
impl Handler<ms::JoinGrih> for ChatPinnd { impl Handler<ms::JoinGrih> for ChatPinnd {
type Result = Result<(), errors::GrihFullError>; type Result = Resp;
fn handle(&mut self, msg: ms::JoinGrih, _: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: ms::JoinGrih, _: &mut Self::Context) -> Self::Result {
match self.grih.get_mut(&msg.grih_kunjika) { // check if group exist // check if user exist
if let Some(_) = self.vyaktigat_waitlist.iter().position(|vk| vk.kunjika == msg.kunjika) {
println!("got in watchlist");
return Resp::Err("Kunjika already exist".to_owned());
}
if let Some(_) = self.grih.iter().position(|(_,g)| {
match g.loog.iter().position(|a| {println!("Got in grih {:?} {:?}", a.kunjika, msg.kunjika); a.kunjika == msg.kunjika}) {
Some(_) => true,
None => false
}
}) {
return Resp::Err("Kunjika already exist".to_owned());
}
// check if grih exist and add user
match self.grih.get_mut(&msg.grih_kunjika) {
Some(grih) =>{ // exist Some(grih) =>{ // exist
// check if group have no space left // check if grih have no space left
if let Some(n) = grih.length { if let Some(n) = grih.length {
if grih.loog.len() >= n { if grih.loog.len() >= n {
return Err(errors::GrihFullError); return Resp::Err("Grih have no space".to_owned());
} }
} }
let vayakti = self.non_connected_vyakti.get(&msg.kunjika).unwrap(); grih.loog.iter().for_each(|a: &Loog| {
let name = vayakti.name.to_owned();
let tags = vayakti.tags.to_owned();
let name_tmp = name.clone();
let kunjika_tmp = msg.kunjika.clone();
grih.loog.iter().for_each(move |a: &Loog| {
a.addr.do_send(ms::WsConnected { a.addr.do_send(ms::WsConnected {
name: name_tmp.clone(), name: msg.name.to_owned(),
kunjika: kunjika_tmp.clone() kunjika: msg.kunjika.to_owned()
}) })
}); });
self.non_connected_vyakti.remove(&msg.kunjika).unwrap_or(());
grih.loog.push(Loog::new(msg.addr, msg.kunjika,name,tags)); grih.loog.push(Loog::new(msg.addr, msg.kunjika,msg.name, None));
}, None => { // don't exist }, None => { // don't exist
// add group and notify // add grih and notify
let vayakti = self.non_connected_vyakti.get(&msg.kunjika).unwrap();
msg.addr.do_send(ms::WsConnected { msg.addr.do_send(ms::WsConnected {
name: vayakti.name.clone(), name: msg.name.to_owned(),
kunjika: msg.kunjika.clone() kunjika: msg.kunjika.to_owned()
}); });
self.grih.insert(msg.grih_kunjika, Grih { self.grih.insert(msg.grih_kunjika, Grih {
length: msg.length, length: msg.length,
loog: vec![Loog::new(msg.addr,msg.kunjika.clone(),vayakti.name.clone(),vayakti.tags.clone())] loog: vec![Loog::new(msg.addr,msg.kunjika,msg.name, None)]
}); });
self.non_connected_vyakti.remove(&msg.kunjika).unwrap_or(());
} }
} }
Ok(()) Resp::Ok
} }
} }
@ -132,50 +111,165 @@ impl Handler<ms::JoinGrih> for ChatPinnd {
/// Check if watchlist is empty, if yes add the kunjika andaddr to watchlist /// Check if watchlist is empty, if yes add the kunjika andaddr to watchlist
/// if watchlist have people get 0th person an connect it /// if watchlist have people get 0th person an connect it
impl Handler<ms::JoinRandom> for ChatPinnd { impl Handler<ms::JoinRandom> for ChatPinnd {
type Result = Option<()>; type Result = Resp;
fn handle(&mut self, msg: ms::JoinRandom, _: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: ms::JoinRandom, _: &mut Self::Context) -> Self::Result {
// check if user exist
if let Some(_) = self.vyaktigat_waitlist.iter().position(|vk| vk.kunjika == msg.kunjika) {
return Resp::Err("Kunjika already exist".to_owned());
}
if let Some(_) = self.grih.iter().position(|(_,g)| {
match g.loog.iter().position(|a| a.kunjika == msg.kunjika) {
Some(_) => true,
None => false
}
}) {
return Resp::Err("Kunjika already exist".to_owned());
}
// Check if watch list is empty // Check if watch list is empty
if self.vyaktigat_waitlist.len() == 0 { if self.vyaktigat_waitlist.len() == 0 {
self.vyaktigat_waitlist.push(VyaktiWatchlist { self.vyaktigat_waitlist.push(VyaktiWatchlist {
kunjika: msg.kunjika, kunjika: msg.kunjika,
addr: msg.addr addr: msg.addr,
name: msg.name,
tags: msg.tags
}); });
return None; return Resp::None;
} }
// connect 0th person // connect person with tag or to zero
let vayakti_watchlist = self.vyaktigat_waitlist.remove(0); let pos = match self.vyaktigat_waitlist.iter().position(|vk| {
let vayakti1_name: String; match vk.tags.iter().position(|t| msg.tags.contains(t)) {
let vayakti2_name: String; Some(_) => true,
let group_kunjika: String; None => false
{ }
let vayakti1 = self.non_connected_vyakti.get(&msg.kunjika).unwrap(); }) {
let vayakti2 = self.non_connected_vyakti.get(&vayakti_watchlist.kunjika).unwrap(); Some(i) => i,
vayakti1_name = vayakti1.name.clone(); None => {
vayakti2_name = vayakti2.name.clone(); self.vyaktigat_waitlist.push(VyaktiWatchlist {
group_kunjika = format!("gupt_{}>{}",msg.kunjika.clone(), vayakti_watchlist.kunjika); kunjika: msg.kunjika,
self.grih.insert(group_kunjika.clone(), Grih { addr: msg.addr,
length: Some(2), name: msg.name,
loog: vec![Loog::new(msg.addr.clone(), msg.kunjika.clone(), vayakti1.name.clone(), vayakti1.tags.clone()), tags: msg.tags
Loog::new(vayakti_watchlist.addr.clone(), vayakti_watchlist.kunjika.clone(), vayakti2.name.clone(), vayakti2.tags.clone())] });
}); return Resp::None;
} }
};
self.non_connected_vyakti.remove(&msg.kunjika).unwrap_or(()); let vayakti_watchlist = self.vyaktigat_waitlist.remove(pos);
self.non_connected_vyakti.remove(&vayakti_watchlist.kunjika).unwrap_or(()); let group_kunjika = format!("gupt_{}>{}",msg.kunjika.to_owned(), vayakti_watchlist.kunjika);
self.grih.insert(group_kunjika.to_owned(), Grih {
length: Some(2),
loog: vec![Loog::new(msg.addr.clone(), msg.kunjika.to_owned(), msg.name.to_owned(), Some(msg.tags.clone())),
Loog::new(vayakti_watchlist.addr.clone(), vayakti_watchlist.kunjika.to_owned(), vayakti_watchlist.name.to_owned(), Some(vayakti_watchlist.tags.clone()))]
});
// notify about connection // notify about connection
msg.addr.do_send(ms::WsConnectedRandom { msg.addr.do_send(ms::WsConnectedRandom {
ajnyat_name: vayakti2_name, name: vayakti_watchlist.name,
grih_kunjika: group_kunjika.clone() kunjika: vayakti_watchlist.kunjika,
grih_kunjika: group_kunjika.to_owned()
}); });
vayakti_watchlist.addr.do_send(ms::WsConnectedRandom { vayakti_watchlist.addr.do_send(ms::WsConnectedRandom {
ajnyat_name: vayakti1_name, name: msg.name,
kunjika: msg.kunjika.to_owned(),
grih_kunjika: group_kunjika grih_kunjika: group_kunjika
}); });
Some(()) Resp::Ok
}
}
/// Next Random user
impl Handler<ms::JoinRandomNext> for ChatPinnd {
type Result = Resp;
fn handle(&mut self, msg: ms::JoinRandomNext, _: &mut Self::Context) -> Self::Result {
let grih = self.grih.get_mut(&msg.grih_kunjika).unwrap();
let loog_i = grih.loog.iter().position(|a| a.kunjika == msg.kunjika).unwrap();
let addr;
let name;
let tags;
{
let loog = grih.loog.get(0).unwrap();
if let None = loog.tags {
return Resp::Err("You are not a randome vyakti!".to_owned());
}
addr = loog.addr.clone();
name = loog.name.to_owned();
tags = loog.tags.clone().unwrap();
}
// Check if watch list is empty
if self.vyaktigat_waitlist.len() == 0 {
self.vyaktigat_waitlist.push(VyaktiWatchlist {
kunjika: msg.kunjika,
addr,
name,
tags
});
return Resp::None;
}
// connect person with tag or to zero
let tags = tags.clone();
let pos = match self.vyaktigat_waitlist.iter().position(|vk| {
match vk.tags.iter().position(|t| tags.contains(t)) {
Some(_) => true,
None => false
}
}) {
Some(i) => i,
None => {
self.vyaktigat_waitlist.push(VyaktiWatchlist {
kunjika: msg.kunjika,
addr,
name,
tags
});
return Resp::None;
}
};
let vayakti_watchlist = self.vyaktigat_waitlist.remove(pos);
let group_kunjika = format!("gupt_{}>{}",msg.kunjika.to_owned(), vayakti_watchlist.kunjika);
grih.loog.remove(loog_i);
grih.loog.iter().for_each(|a| {
a.addr.do_send(ms::WsDisconnected {
kunjika: msg.kunjika.to_owned(),
name: name.to_owned()
})
});
let log_count = grih.loog.len();
drop(grih);
if log_count == 0 {
self.grih.remove(&msg.grih_kunjika);
}
self.grih.insert(group_kunjika.to_owned(), Grih {
length: Some(2),
loog: vec![Loog::new(addr.clone(), msg.kunjika.to_owned(), name.to_owned(), Some(tags.clone())),
Loog::new(vayakti_watchlist.addr.clone(), vayakti_watchlist.kunjika.to_owned(), vayakti_watchlist.name.to_owned(), Some(vayakti_watchlist.tags.clone()))]
});
// notify about connection
addr.do_send(ms::WsConnectedRandom {
name: vayakti_watchlist.name,
kunjika: vayakti_watchlist.kunjika,
grih_kunjika: group_kunjika.to_owned()
});
vayakti_watchlist.addr.do_send(ms::WsConnectedRandom {
name,
kunjika: msg.kunjika.to_owned(),
grih_kunjika: group_kunjika
});
Resp::Ok
} }
} }
@ -187,9 +281,9 @@ impl Handler<ms::SendText> for ChatPinnd {
if let Some(grih) = self.grih.get(&msg.grih_kunjika) { if let Some(grih) = self.grih.get(&msg.grih_kunjika) {
grih.loog.iter().for_each(|c| { grih.loog.iter().for_each(|c| {
c.addr.do_send(ms::WsText { c.addr.do_send(ms::WsText {
sender_kunjika: msg.kunjika.clone(), sender_kunjika: msg.kunjika.to_owned(),
text: msg.text.clone(), text: msg.text.to_owned(),
reply: msg.reply.clone() reply: msg.reply.to_owned()
}); });
}); });
} }
@ -204,8 +298,8 @@ impl Handler<ms::SendStatus> for ChatPinnd {
if let Some(grih) = self.grih.get(&msg.grih_kunjika) { if let Some(grih) = self.grih.get(&msg.grih_kunjika) {
grih.loog.iter().for_each(|c| { grih.loog.iter().for_each(|c| {
c.addr.do_send(ms::WsStatus { c.addr.do_send(ms::WsStatus {
sender_kunjika: msg.kunjika.clone(), sender_kunjika: msg.kunjika.to_owned(),
status: msg.status.clone(), status: msg.status.to_owned(),
}); });
}); });
} }
@ -220,7 +314,7 @@ impl Handler<ms::List> for ChatPinnd {
if let Some(grih) = self.grih.get(&msg.grih_kunjika) { if let Some(grih) = self.grih.get(&msg.grih_kunjika) {
let mut list = Vec::new(); let mut list = Vec::new();
for x in grih.loog.iter() { for x in grih.loog.iter() {
list.push((x.kunjika.clone(),x.name.clone())); list.push((x.kunjika.to_owned(),x.name.to_owned()));
} }
serde_json::json!(list).to_string() serde_json::json!(list).to_string()
} else { } else {
@ -236,23 +330,23 @@ impl Handler<ms::LeaveUser> for ChatPinnd {
fn handle(&mut self, msg: ms::LeaveUser, _: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: ms::LeaveUser, _: &mut Self::Context) -> Self::Result {
if let Some(grih_kunjika) = &msg.grih_kunjika { if let Some(grih_kunjika) = &msg.grih_kunjika {
if let Some(grih) = self.grih.get_mut(grih_kunjika) { if let Some(grih) = self.grih.get_mut(grih_kunjika) {
if let Some(i) = grih.loog.iter().position(|x| x.addr == msg.addr) { let name = if let Some(i) = grih.loog.iter().position(|x| x.addr == msg.addr) {
grih.loog.remove(i); grih.loog.remove(i).name
} } else { "".to_owned() };
if grih.loog.len() == 0 { if grih.loog.len() == 0 {
self.grih.remove(grih_kunjika); self.grih.remove(grih_kunjika);
} else { } else {
grih.loog.iter().for_each(|a| { grih.loog.iter().for_each(|a| {
a.addr.do_send(ms::WsDisconnected { a.addr.do_send(ms::WsDisconnected {
kunjika: msg.kunjika.clone() kunjika: msg.kunjika.to_owned(),
name: name.to_owned()
}) })
}); });
} }
} }
} }
self.non_connected_vyakti.remove(&msg.kunjika).unwrap_or(());
if let Some(i) = self.vyaktigat_waitlist.iter().position(|a| a.kunjika == msg.kunjika) { if let Some(i) = self.vyaktigat_waitlist.iter().position(|a| a.kunjika == msg.kunjika) {
self.vyaktigat_waitlist.remove(i); self.vyaktigat_waitlist.remove(i);
} }
@ -263,8 +357,7 @@ impl Default for ChatPinnd {
fn default() -> Self { fn default() -> Self {
ChatPinnd { ChatPinnd {
grih: HashMap::new(), grih: HashMap::new(),
vyaktigat_waitlist: Vec::new(), vyaktigat_waitlist: Vec::new()
non_connected_vyakti: VecMap::new()
} }
} }
} }
@ -273,12 +366,13 @@ impl Loog {
fn new(addr: Addr<ws_sansad::WsSansad>, fn new(addr: Addr<ws_sansad::WsSansad>,
kunjika: String, kunjika: String,
name: String, name: String,
tags: Vec<String>) -> Self { tags: Option<Vec<String>>) -> Self {
Loog { Loog {
addr, addr,
kunjika, kunjika,
name, name,
_tags:tags tags
} }
} }
} }

View File

@ -1,4 +1,5 @@
use std::fmt; use std::fmt;
use std::error::Error;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AlreadyExistError; pub struct AlreadyExistError;
@ -8,3 +9,7 @@ impl fmt::Display for AlreadyExistError {
write!(f, "User kunjika already exist!") write!(f, "User kunjika already exist!")
} }
} }
impl Error for AlreadyExistError {
}

View File

@ -1,35 +1,37 @@
//! Messages to be sent between Actors //! Messages to be sent between Actors
use actix::prelude::*; use actix::prelude::*;
use dev::{MessageResponse, ResponseChannel};
use crate::ws_sansad::WsSansad; use crate::ws_sansad::WsSansad;
use crate::errors;
//################################################## For ChatPinnd ################################################## //################################################## For ChatPinnd ##################################################
/// Request to change information of vayakti to list of vayakti im ChatPind /// Request to change information of vayakti to list of vayakti im ChatPind
#[derive(Clone, Message)]
#[rtype(result = "Option<String>")] // None if no error
pub struct SetInfoVyakti {
pub kunjika: String,
pub name: String,
pub tags: Vec<String>,
pub modify: bool
}
/// Request to Grih with its kunjika /// Request to Grih with its kunjika
#[derive(Clone, Message)] #[derive(Clone, Message)]
#[rtype(result = "Result<(), errors::GrihFullError>")] #[rtype(result = "Resp")]
pub struct JoinGrih { pub struct JoinGrih {
pub grih_kunjika: String, pub grih_kunjika: String,
pub length: Option<usize>, pub length: Option<usize>,
pub addr: Addr<WsSansad>, pub addr: Addr<WsSansad>,
pub kunjika: String pub kunjika: String,
pub name: String,
} }
/// Request to connect Random vayakti /// Request to connect Random vayakti
#[derive(Clone, Message)] #[derive(Clone, Message)]
#[rtype(result = "Option<()>")] #[rtype(result = "Resp")]
pub struct JoinRandom { pub struct JoinRandom {
pub addr: Addr<WsSansad>, pub addr: Addr<WsSansad>,
pub kunjika: String,
pub name: String,
pub tags: Vec<String>,
}
/// Request to connect Random vayakti
#[derive(Clone, Message)]
#[rtype(result = "Resp")]
pub struct JoinRandomNext {
pub grih_kunjika: String,
pub kunjika: String pub kunjika: String
} }
@ -93,7 +95,6 @@ pub struct WsList {
pub json: String pub json: String
} }
// Notify Someone connected // Notify Someone connected
#[derive(Clone, Message)] #[derive(Clone, Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
@ -106,7 +107,8 @@ pub struct WsConnected {
#[derive(Clone, Message)] #[derive(Clone, Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct WsDisconnected { pub struct WsDisconnected {
pub kunjika: String pub kunjika: String,
pub name: String
} }
// Give response message // Give response message
@ -121,7 +123,25 @@ pub struct WsResponse {
#[derive(Clone, Message)] #[derive(Clone, Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct WsConnectedRandom { pub struct WsConnectedRandom {
pub ajnyat_name: String, pub name: String,
pub kunjika: String,
pub grih_kunjika: String pub grih_kunjika: String
} }
//################################################## Helper ##################################################
pub enum Resp {
Ok,
Err(String),
None
}
impl<A, M> MessageResponse<A, M> for Resp
where
A: Actor,
M: Message<Result = Resp>,
{
fn handle<R: ResponseChannel<M>>(self, _: &mut A::Context, tx: Option<R>) {
if let Some(tx) = tx {
tx.send(self);
}
}
}

View File

@ -2,15 +2,22 @@
use actix::prelude::*; use actix::prelude::*;
use actix_broker::{Broker, SystemBroker}; use actix_broker::{Broker, SystemBroker};
use actix_web_actors::ws; use actix_web_actors::ws;
use ms::Resp;
use serde_json::{json, Value}; use serde_json::{json, Value};
use std::time::{Duration, Instant};
use crate::{chat_pinnd::ChatPinnd, messages as ms, validator::{Validation as vl, validate}}; use crate::{chat_pinnd::ChatPinnd, messages as ms, validator::{Validation as vl, validate}};
use crate::errors;
/// How often heartbeat pings are sent
const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5);
/// How long before lack of client response causes a timeout
const CLIENT_TIMEOUT: Duration = Duration::from_secs(10);
pub struct WsSansad { pub struct WsSansad {
kunjika: Option<String>, kunjika: String,
isthiti: Isthiti, isthiti: Isthiti,
addr: Option<Addr<Self>>, addr: Option<Addr<Self>>,
hb: Instant
} }
#[derive(Debug)] #[derive(Debug)]
@ -25,6 +32,7 @@ impl Actor for WsSansad {
fn started(&mut self, ctx: &mut Self::Context) { fn started(&mut self, ctx: &mut Self::Context) {
self.addr = Some(ctx.address().clone()); // own addr self.addr = Some(ctx.address().clone()); // own addr
self.hb(ctx);
} }
fn stopping(&mut self, _: &mut Self::Context) -> Running { fn stopping(&mut self, _: &mut Self::Context) -> Running {
@ -37,14 +45,18 @@ impl Actor for WsSansad {
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsSansad { impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsSansad {
fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) { fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
match msg { match msg {
Ok(ws::Message::Ping(msg)) => ctx.ping(&msg), Ok(ws::Message::Ping(msg)) => {
Ok(ws::Message::Text(msg)) => { ctx.ping(&msg);
self.hb = Instant::now();
}, Ok(ws::Message::Pong(_)) => {
self.hb = Instant::now();
}, Ok(ws::Message::Text(msg)) => {
futures::executor::block_on(self.parse_text_handle(msg)); futures::executor::block_on(self.parse_text_handle(msg));
}, }, Ok(ws::Message::Close(msg)) => {
Ok(ws::Message::Close(msg)) => {
ctx.close(msg); ctx.close(msg);
ctx.stop();
} }
_ => ctx.close(None) _ => ctx.stop()
} }
} }
} }
@ -69,7 +81,7 @@ impl Handler<ms::WsStatus> for WsSansad {
type Result = (); type Result = ();
fn handle(&mut self, msg: ms::WsStatus, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: ms::WsStatus, ctx: &mut Self::Context) -> Self::Result {
let json = json!({ let json = json!({
"cmd": "text", "cmd": "status",
"status": msg.status, "status": msg.status,
"kunjika": msg.sender_kunjika // Sender's kunjuka "kunjika": msg.sender_kunjika // Sender's kunjuka
}); });
@ -121,7 +133,8 @@ impl Handler<ms::WsDisconnected> for WsSansad {
fn handle(&mut self, msg: ms::WsDisconnected, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: ms::WsDisconnected, ctx: &mut Self::Context) -> Self::Result {
let json = json!({ let json = json!({
"cmd": "disconnected", "cmd": "disconnected",
"name": msg.kunjika "name": msg.name,
"kunjika": msg.kunjika
}); });
ctx.text(json.to_string()); ctx.text(json.to_string());
} }
@ -133,8 +146,9 @@ impl Handler<ms::WsConnectedRandom> for WsSansad {
fn handle(&mut self, msg: ms::WsConnectedRandom, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: ms::WsConnectedRandom, ctx: &mut Self::Context) -> Self::Result {
self.isthiti = Isthiti::Grih(msg.grih_kunjika); self.isthiti = Isthiti::Grih(msg.grih_kunjika);
let json = json!({ let json = json!({
"cmd": "connected", "cmd": "random",
"ajnyat": msg.ajnyat_name "name": msg.name,
"kunjika": msg.kunjika
}); });
ctx.text(json.to_string()); ctx.text(json.to_string());
} }
@ -143,20 +157,41 @@ impl Handler<ms::WsConnectedRandom> for WsSansad {
impl WsSansad { impl WsSansad {
pub fn new() -> Self { pub fn new() -> Self {
WsSansad { WsSansad {
kunjika: None, kunjika: String::new(),
isthiti: Isthiti::None, isthiti: Isthiti::None,
addr: None, addr: None,
hb: Instant::now()
} }
} }
/// helper method that sends ping to client every second.
///
/// also this method checks heartbeats from client
fn hb(&self, ctx: &mut <Self as Actor>::Context) {
ctx.run_interval(HEARTBEAT_INTERVAL, |act, ctx| {
// check client heartbeats
if Instant::now().duration_since(act.hb) > CLIENT_TIMEOUT {
// heartbeat timed out
println!("Websocket Client heartbeat failed, disconnecting!");
// stop actor
ctx.stop();
// don't try to send a ping
return;
}
ctx.ping(b"");
});
}
/// parse the request text from client /// parse the request text from client
async fn parse_text_handle(&mut self, msg: String) { async fn parse_text_handle(&mut self, msg: String) {
println!("{:?}", msg);
if let Ok(val) = serde_json::from_str::<Value>(&msg) { if let Ok(val) = serde_json::from_str::<Value>(&msg) {
match val.get("cmd").unwrap().as_str().unwrap() { match val.get("cmd").unwrap().as_str().unwrap() {
"seinfo" => { self.set_info(val).await },
"join" => { self.join_grih(val).await }, "join" => { self.join_grih(val).await },
"rand" => { self.join_random().await }, "rand" => { self.join_random(val).await },
"randnext" => { self.join_random_next().await },
"text" => { self.send_text(val).await }, "text" => { self.send_text(val).await },
"status" => { self.send_status(val).await }, "status" => { self.send_status(val).await },
"list" => { self.list().await }, "list" => { self.list().await },
@ -181,10 +216,17 @@ impl WsSansad {
message: text.to_owned() message: text.to_owned()
}); });
} }
/// Request for joining to random person
async fn join_random(&mut self, val: Value) {
// Check is already joined
match self.isthiti {
Isthiti::None => (),
Isthiti::VraktigatWaitlist => {
self.send_ok_response("watchlist");
return;
}, Isthiti::Grih(_) => return
}
/// send info of user and modify if needed
async fn set_info(&mut self, val: Value) {
// parse parameters
let kunjika = match val.get("kunjika") { let kunjika = match val.get("kunjika") {
Some(val ) => val.as_str().unwrap().to_owned(), Some(val ) => val.as_str().unwrap().to_owned(),
None => { None => {
@ -222,32 +264,69 @@ impl WsSansad {
return; return;
} }
// check if eing modified // request
let modify = self.kunjika == Some(kunjika.clone()); let result: Resp = ChatPinnd::from_registry().send(ms::JoinRandom{
addr: self.addr.clone().unwrap(),
//request kunjika: kunjika.to_owned(),
let result: Option<String> = ChatPinnd::from_registry().send(ms::SetInfoVyakti {
kunjika: kunjika.clone(),
name, name,
tags, tags
modify
}).await.unwrap(); }).await.unwrap();
if let Some(msg) = result { match result {
self.send_err_response(&msg); Resp::Err(err) => self.send_err_response(&err),
return; Resp::Ok => self.kunjika = kunjika,
Resp::None => {
self.addr.clone().unwrap().do_send(ms::WsResponse{
result: "watch".to_owned() ,
message: "Watchlist".to_owned()
});
self.isthiti = Isthiti::VraktigatWaitlist;
self.kunjika = kunjika
}
} }
self.kunjika = Some(kunjika);
self.send_ok_response("info changed");
} }
/// Request for joining to random person /// Request for joining to random person
async fn join_random(&mut self) { async fn join_random_next(&mut self) {
// check if vayakti exist // Check is already joined
if let None = self.kunjika { let grih_kunjika = match &self.isthiti {
self.send_err_response("No vayakti kunjika set"); Isthiti::VraktigatWaitlist => {
return; self.send_ok_response("watchlist");
return;
},
Isthiti::Grih(grih_kunjika) => grih_kunjika,
Isthiti::None => {
self.send_ok_response("Not allowed");
return;
}
};
// request
let result: Resp = ChatPinnd::from_registry().send(ms::JoinRandomNext{
kunjika: self.kunjika.to_owned(),
grih_kunjika: grih_kunjika.to_owned(),
}).await.unwrap();
match result {
Resp::Err(err) => self.send_err_response(&err),
Resp::None => {
self.addr.clone().unwrap().do_send(ms::WsResponse{
result: "watch".to_owned() ,
message: "Watchlist".to_owned()
});
self.isthiti = Isthiti::VraktigatWaitlist;
self.kunjika = self.kunjika.to_owned()
}
_ => ()
}
}
/// Request to join to grih
async fn join_grih(&mut self, val: Value) {
// Check is already joined
match self.isthiti {
Isthiti::None => (),
_ => return
} }
// is vayakti in watch list // is vayakti in watch list
@ -256,50 +335,27 @@ impl WsSansad {
return; return;
} }
// request let kunjika = match val.get("kunjika") {
let result: Option<()> = ChatPinnd::from_registry().send(ms::JoinRandom{ Some(val ) => val.as_str().unwrap().to_owned(),
addr: self.addr.clone().unwrap(),
kunjika: self.kunjika.clone().unwrap()
}).await.unwrap();
if let None = result {
self.send_ok_response("watchlist");
self.isthiti = Isthiti::VraktigatWaitlist;
}
}
/// Request to join to grih
async fn join_grih(&mut self, val: Value) {
//check user exist
if let None = self.kunjika {
self.send_err_response("No vayakti kunjika set");
return;
}
// Check is already joined
match self.isthiti {
Isthiti::None => (),
_ => {
return;
}
}
// parse parameter
let grih_kunjika = match val.get("grih_kunjika") {
Some(val) => val,
None => { None => {
self.send_err_response("Invalid request"); self.send_err_response("Invalid request");
return; return;
} }
}.as_str().unwrap().to_owned(); };
println!("about to validate"); let name = match val.get("name") {
// Validate Some(val ) => val.as_str().unwrap().to_owned(),
if let Some(val ) = validate(vec![vl::NonEmpty, vl::NoGupt, vl::NoSpace], &grih_kunjika, "Grih Kunjika") { None => {
println!("{}", val); self.send_err_response("Invalid request");
self.send_err_response(&val); return;
return; }
} };
let grih_kunjika = match val.get("grih_kunjika") {
Some(val ) => val.as_str().unwrap().to_owned(),
None => {
self.send_err_response("Invalid request");
return;
}
};
let length: Option<usize> = match val.get("length") { let length: Option<usize> = match val.get("length") {
Some(val) => match val.as_i64(){ Some(val) => match val.as_i64(){
Some(val) => Some(val as usize), Some(val) => Some(val as usize),
@ -308,30 +364,47 @@ impl WsSansad {
None => None None => None
}; };
println!("{:?} {:?} {:?}", grih_kunjika, self.kunjika, length);
// Validate
if let Some(val ) = validate(vec![vl::NonEmpty, vl::NoSpace, vl::NoHashtag], &kunjika, "Kunjika") {
self.send_err_response(&val);
return;
}
if let Some(val ) = validate(vec![vl::NonEmpty], &name, "Name") {
self.send_err_response(&val);
return;
}
if let Some(val ) = validate(vec![vl::NonEmpty, vl::NoGupt, vl::NoSpace], &grih_kunjika, "Grih Kunjika") {
self.send_err_response(&val);
return;
}
// request // request
let result: Result<(), errors::GrihFullError> = ChatPinnd::from_registry().send(ms::JoinGrih { let result: Resp = ChatPinnd::from_registry().send(ms::JoinGrih {
grih_kunjika: grih_kunjika.clone(), grih_kunjika: grih_kunjika.to_owned(),
length, length,
addr: self.addr.clone().unwrap(), addr: self.addr.clone().unwrap(),
kunjika: self.kunjika.clone().unwrap() kunjika: kunjika.to_owned(),
name
}).await.unwrap(); }).await.unwrap();
match result { match result {
Ok(_) => { Resp::Err(err) => self.send_err_response(&err),
Resp::Ok => {
self.isthiti = Isthiti::Grih(grih_kunjika); self.isthiti = Isthiti::Grih(grih_kunjika);
self.kunjika = kunjika;
self.send_ok_response("joined") self.send_ok_response("joined")
}, }
Err(e) => self.send_err_response(&format!("{}", e)) _ => ()
} }
} }
/// Request to join to grih /// Request to join to grih
async fn list(&mut self) { async fn list(&mut self) {
// check if vayakti exist // check if vayakti exist
if let None = self.kunjika { if let Isthiti::None = self.isthiti {
self.send_err_response("No vayakti kunjika set"); self.send_err_response("Not in any Grih");
return; return;
} }
@ -339,7 +412,7 @@ impl WsSansad {
match &self.isthiti { match &self.isthiti {
Isthiti::Grih(kunjika) => { Isthiti::Grih(kunjika) => {
let json: String = ChatPinnd::from_registry().send(ms::List { let json: String = ChatPinnd::from_registry().send(ms::List {
grih_kunjika: kunjika.clone() grih_kunjika: kunjika.to_owned()
}).await.unwrap(); }).await.unwrap();
self.addr.clone().unwrap().do_send(ms::WsList { self.addr.clone().unwrap().do_send(ms::WsList {
@ -356,8 +429,8 @@ impl WsSansad {
/// send text to vayakti in grih /// send text to vayakti in grih
async fn send_text(&mut self, val: Value) { async fn send_text(&mut self, val: Value) {
// check if vayakti exist // check if vayakti exist
if let None = self.kunjika { if let Isthiti::None = self.isthiti {
self.send_err_response("No vayakti kunjika set"); self.send_err_response("Not in any Grih");
return; return;
} }
@ -385,15 +458,15 @@ impl WsSansad {
}; };
let grih_kunjika = match &self.isthiti { let grih_kunjika = match &self.isthiti {
Isthiti::Grih(g) => { Isthiti::Grih(grih_kunjika) => {
g.clone() grih_kunjika.to_owned()
}, _ => { }, _ => {
return; return;
} }
}; };
Broker::<SystemBroker>::issue_async(ms::SendText { Broker::<SystemBroker>::issue_async(ms::SendText {
grih_kunjika, grih_kunjika,
kunjika: self.kunjika.clone().unwrap(), kunjika: self.kunjika.to_owned(),
text, text,
reply reply
}); });
@ -402,8 +475,8 @@ impl WsSansad {
/// send status to vayakti in grih /// send status to vayakti in grih
async fn send_status(&mut self, val: Value) { async fn send_status(&mut self, val: Value) {
// check if vayakti exist // check if vayakti exist
if let None = self.kunjika { if let Isthiti::None = self.isthiti {
self.send_err_response("No vayakti kunjika set"); self.send_err_response("Not in any Grih");
return; return;
} }
@ -425,34 +498,32 @@ impl WsSansad {
} }
}.as_str().unwrap().to_owned(); }.as_str().unwrap().to_owned();
let grih_kunjika = match &self.isthiti { let grih_kunjika = match &self.isthiti {
Isthiti::Grih(g) => { Isthiti::Grih(grih_kunjika) => {
g.clone() grih_kunjika.to_owned()
}, _ => { }, _ => {
return; return;
} }
}; };
Broker::<SystemBroker>::issue_async(ms::SendStatus { Broker::<SystemBroker>::issue_async(ms::SendStatus {
grih_kunjika, grih_kunjika,
kunjika: self.kunjika.clone().unwrap(), kunjika: self.kunjika.to_owned(),
status status
}); });
} }
// notify leaving /// notify leaving
async fn leave_grih(&mut self) { async fn leave_grih(&mut self) {
let grih_kunjika = match &self.isthiti { let grih_kunjika = match &self.isthiti {
Isthiti::Grih(val) => Some(val.to_owned()), Isthiti::Grih(val) => Some(val.to_owned()),
_ => None _ => None
}; };
if let Some(ku) = &self.kunjika { Broker::<SystemBroker>::issue_async(ms::LeaveUser {
Broker::<SystemBroker>::issue_async(ms::LeaveUser { grih_kunjika,
grih_kunjika, kunjika: self.kunjika.to_owned(),
kunjika: addr: self.addr.clone().unwrap()
ku.to_owned(), });
addr: self.addr.clone().unwrap()
});
}
self.isthiti = Isthiti::None; self.isthiti = Isthiti::None;
self.send_ok_response("left"); self.send_ok_response("left");

View File

@ -3,6 +3,7 @@ pre {
font-size: 0.9em; font-size: 0.9em;
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
white-space: pre-wrap;
} }
textarea { textarea {

View File

@ -30,7 +30,7 @@
<div name="error_area" class="siimple-content siimple--py-1 siimple--text-small siimple--color-primary siimple-content--fluid"></div> <div name="error_area" class="siimple-content siimple--py-1 siimple--text-small siimple--color-primary siimple-content--fluid"></div>
<div class="siimple-form-detail">Connect Grih(home) with kunjika.</div> <div class="siimple-form-detail">Connect Grih(home) with kunjika.</div>
<div class="siimple-form-field"> <div class="siimple-form-field">
<div class="siimple-form-field-label">Grih kunjika(id)</div> <div class="siimple-form-field-label">Grih kunjika(home id)</div>
<input name="grih_kunjika" type="text" class="siimple-input siimple-input--fluid" placeholder="Grih kunjika"> <input name="grih_kunjika" type="text" class="siimple-input siimple-input--fluid" placeholder="Grih kunjika">
<div class="siimple-form-field-helper">New group is created if no such group exists</div> <div class="siimple-form-field-helper">New group is created if no such group exists</div>
</div> </div>
@ -66,7 +66,7 @@
<div class="siimple-form-field"> <div class="siimple-form-field">
<div class="siimple-form-field-label">Tags</div> <div class="siimple-form-field-label">Tags</div>
<input name="tags" type="text" class="siimple-input siimple-input--fluid" placeholder="Tags"> <input name="tags" type="text" class="siimple-input siimple-input--fluid" placeholder="Tags">
<div class="siimple-form-field-helper">Seperated by space</div> <div class="siimple-form-field-helper">Seperated by space. Leave empty to connect anyone. Its recommended to try without tags if you don't get anyone</div>
</div> </div>
<div class="siimple-form-field siimple--text-right" style="width: 100%;"> <div class="siimple-form-field siimple--text-right" style="width: 100%;">
<div><span name="error_msg" class="siimple-tag siimple-tag--error siimple--my-2 hidden"></span></div> <div><span name="error_msg" class="siimple-tag siimple-tag--error siimple--my-2 hidden"></span></div>
@ -85,14 +85,14 @@
</div> </div>
<a class="siimple-navbar-title"><img src="img/label-l.svg" alt="Lupt Chat" height="34px"></a> <a class="siimple-navbar-title"><img src="img/label-l.svg" alt="Lupt Chat" height="34px"></a>
<div class="siimple--float-right"> <div class="siimple--float-right">
<a class="siimple-navbar-item">Next &rightarrow;</a> <a id="next_btn" onclick="connect_next()" class="siimple-navbar-item">Next &rightarrow;</a>
</div> </div>
</div> </div>
<div id="message_area_scroll" style="height: calc(100% - 2*44px - 2*5px); padding: 5px; overflow-y: scroll;" class="siimple--bg-light"> <div id="message_area_scroll" style="height: calc(100% - 2*44px - 2*5px); padding: 5px; overflow-y: scroll;" class="siimple--bg-light">
<div id="message_area" class="siimple--my-1"> <div id="message_area" class="siimple--my-1">
</div> </div>
<div id="message_area" class="siimple--my-1"> <div id="status_area" class="siimple--my-1">
</div> </div>
</div> </div>
@ -134,7 +134,36 @@
</div> </div>
<div> <div>
<a onclick="cleanMessage()" class="siimple-btn siimple-btn--blue">Clear</a> <a onclick="cleanMessage()" class="siimple-btn siimple-btn--blue">Clear</a>
<a class="siimple-btn siimple-btn--blue">List Users</a> <a onclick="vayaktiList()" class="siimple-btn siimple-btn--blue">List Vyakti(Users)</a>
</div>
</div>
<!-- Vyakti List -->
<div id="vayakti_model" class="siimple-modal siimple-modal--large hidden" style="z-index: 9999;" id="modal">
<div class="siimple-modal-content">
<div class="siimple-modal-header">
<div class="siimple-modal-header-title">List Vyakti(Users)</div>
<div onclick="$('#vayakti_model').addClass('hidden')" class="siimple-modal-header-close" id="modal-close"></div>
</div>
<div class="siimple-modal-body siimple--px-0">
<div class="siimple-table siimple--px-3">
<div class="siimple-table-header">
<div class="siimple-table-row">
<div class="siimple-table-cell">Name</div>
<div class="siimple-table-cell">Kunjika</div>
</div>
</div>
<div id="vayakti_list" class="siimple-table-body">
<div class="siimple-table-row">
<div class="siimple-table-cell">a</div>
<div class="siimple-table-cell">a</div>
</div>
</div>
</div>
</div>
<div class="siimple-modal-footer siimple--py-2">
<a onclick="$('#vayakti_model').addClass('hidden'); $('#vayakti_list').empty()" class="siimple-btn siimple-btn--blue">Close</a>
</div>
</div> </div>
</div> </div>

View File

@ -20,18 +20,34 @@ $(document).ready(() => {
}); });
$('.message-me, .message-other').click(function() { $('.message-me, .message-other').click(function() {
activateMessage(this); selectMessage(this);
}); });
$('#selected_clip > .siimple-close').click(function() { $('#selected_clip > .siimple-close').click(function() {
deactivateMessages(); unselectMessages();
}); });
var send_typing = false;
var timeout = null;
$('#send_box').keypress(function(e) { $('#send_box').keypress(function(e) {
if(e.originalEvent.charCode == 13 && !e.shiftKey) { if(e.originalEvent.charCode == 13 && !e.shiftKey) {
send(); send();
e.preventDefault(); e.preventDefault();
clearTimeout(timeout);
send_typing = false;
sendTypingEnd()
return
} }
if (!send_typing) {
sendTyping();
send_typing = true;
return;
}
clearTimeout(timeout);
timeout = setTimeout(function() {
send_typing = false;
sendTypingEnd();
},3000);
}); });
$('#send_box').bind('input propertychange keyup', function() { $('#send_box').bind('input propertychange keyup', function() {
@ -47,6 +63,20 @@ $(document).ready(() => {
}); });
}); });
function sendTyping() {
socket.send(JSON.stringify({
cmd: 'status',
status: "typing"
}));
}
function sendTypingEnd() {
socket.send(JSON.stringify({
cmd: 'status',
status: "typing_end"
}));
}
function calcHeight(value) { function calcHeight(value) {
let numberOfLineBreaks = (value.match(/\n/g) || []).length; let numberOfLineBreaks = (value.match(/\n/g) || []).length;
// min-height + lines x line-height + padding + border // min-height + lines x line-height + padding + border
@ -61,7 +91,9 @@ var myinfo = {
kunjika: "", kunjika: "",
name: "" name: ""
}; };
var users = {}; var vayaktiList = {};
var typing = [];
var no_name_message = false;
// Connection opened // Connection opened
socket.addEventListener('open', function (event) { socket.addEventListener('open', function (event) {
@ -71,13 +103,13 @@ socket.addEventListener('open', function (event) {
// Listen for messages // Listen for messages
socket.addEventListener('message', function (event) { socket.addEventListener('message', function (event) {
var j = JSON.parse(event.data); var j = JSON.parse(event.data);
console.log(j);
switch(j.cmd) { switch(j.cmd) {
case 'resp': case 'resp':
if(j.result == 'Err') { if(j.result == 'Err') {
if($('#chat_panel').hasClass('hidden')) { if($('#chat_panel').hasClass('hidden')) {
$('[name="error_msg"]').text(j.message); $('[name="error_msg"]').text(j.message);
$('[name="error_msg"]').removeClass('hidden'); $('[name="error_msg"]').removeClass('hidden');
$('#progressbar').addClass('hidden');
callbacks = []; callbacks = [];
} else { } else {
pushStatus(j.message); pushStatus(j.message);
@ -89,24 +121,49 @@ socket.addEventListener('message', function (event) {
} }
} }
break; break;
case 'random':
callbacks[0]();
callbacks = [];
no_name_message = true;
$('#next_btn').removeClass('hidden');
pushStatus('Say hi to '+j.name);
vayaktiList[j.kunjika] = j.name;
break;
case 'status':
if(j.status == "typing") {
typing.push(j.kunjika);
pushTypingStatus();
} else if(j.status == "typing_end") {
const index = typing.indexOf(j.kunjika);
if (index > -1) typing.splice(index, 1);
pushTypingStatus();
}
break;
case 'text': case 'text':
pushMessage(j.kunjika, j.text, j.reply); pushMessage(j.kunjika, j.text, j.reply);
break; break;
case 'connected': case 'connected':
users[j.kunjika] = j.name; vayaktiList[j.kunjika] = j.name;
pushStatus('Vyakti '+j.name+' connected as '+j.kunjika); pushStatus('Vyakti '+j.name+' connected as '+j.kunjika);
break; break;
case 'disconnected': case 'disconnected':
delete users[j.kunjika]; delete vayaktiList[j.kunjika];
pushStatus('Vyakti '+j.name+' disconnected as '+j.kunjika); pushStatus('Vyakti '+j.name+' disconnected as '+j.kunjika);
break; break;
case 'list':
JSON.parse(j.vayakti).forEach(function(usr) {
vayaktiList[usr[0]] = usr[1];
});
break;
} }
}); });
var joining = false;
function connect(frm) { function connect(frm) {
if(joining) return;
joining = true;
var frm = $(frm); var frm = $(frm);
$('#progressbar').addClass('hidden'); $('#progressbar').removeClass('hidden');
var data = {}; var data = {};
frm.serializeArray().forEach(el => { frm.serializeArray().forEach(el => {
data[el.name] = el.value; data[el.name] = el.value;
@ -115,8 +172,27 @@ function connect(frm) {
data['length'] = parseInt(data['length']); data['length'] = parseInt(data['length']);
} }
callbacks.push(() => { callbacks.push(() => {
socket.send(JSON.stringify(Object.assign({cmd: frm.attr('cmd')}, data))); cleanMessage();
$('#progressbar').addClass('hidden');
$('#send_box').text('');
$('#connect_panel').addClass('hidden');
$('[name="error_msg"]').addClass('hidden');
$('#chat_panel').removeClass('hidden');
$('#send_box').focus();
$('#next_btn').addClass('hidden');
myinfo.kunjika = data.kunjika;
myinfo.name = data.name;
no_name_message = false;
joining = false;
socket.send(JSON.stringify({cmd: 'list'}));
}); });
socket.send(JSON.stringify(Object.assign({cmd: frm.attr('cmd')}, data)));
}
function connect_next() {
if(joining) return;
joining = true;
$('#progressbar').removeClass('hidden');
callbacks.push(() => { callbacks.push(() => {
cleanMessage(); cleanMessage();
$('#progressbar').addClass('hidden'); $('#progressbar').addClass('hidden');
@ -125,10 +201,11 @@ function connect(frm) {
$('[name="error_msg"]').addClass('hidden'); $('[name="error_msg"]').addClass('hidden');
$('#chat_panel').removeClass('hidden'); $('#chat_panel').removeClass('hidden');
$('#send_box').focus(); $('#send_box').focus();
myinfo.kunjika = data.kunjika; $('#next_btn').addClass('hidden');
myinfo.name = data.name; joining = false;
socket.send(JSON.stringify({cmd: 'list'}));
}); });
socket.send(JSON.stringify(Object.assign({cmd: 'seinfo'}, data))); socket.send(JSON.stringify({ cmd: 'randnext' }));
} }
function leave() { function leave() {
@ -138,19 +215,43 @@ function leave() {
$('#selected_clip').addClass('hidden'); $('#selected_clip').addClass('hidden');
$('#action_clip').addClass('hidden'); $('#action_clip').addClass('hidden');
$('#connect_panel').removeClass('hidden'); $('#connect_panel').removeClass('hidden');
myinfo.kunjika = ""; myinfo.kunjika = '';
myinfo.name = ""; myinfo.name = '';
}); });
socket.send(JSON.stringify({ socket.send(JSON.stringify({
cmd: "leave" cmd: 'leave'
})); }));
} }
function pushTypingStatus() {
var elm = $('#status_area > #typing');
if(elm.length > 0) elm.remove();
if(typing.length == 0) return;
var text = '';
typing.forEach((val) => {
text += val + ','
})
text = text.substr(0, text.length-1);
text += ' is typing...'
$('#status_area').append($('<div>', { id: 'typing',
class:'siimple-label siimple--mx-2 siimple--my-0' }).append(text));
var scroll = $("#message_area_scroll");
scroll.scrollTop(scroll[0].scrollHeight);
}
function pushMessage(sender, text, reply = null) { function pushMessage(sender, text, reply = null) {
var isMe = myinfo.kunjika == sender; var isMe = myinfo.kunjika == sender;
var area = $('#message_area'); var area = $('#message_area');
var elm = $('<div>', {class: 'message '+(isMe?'message-me':'message-other')}); var elm = $('<div>', {class: 'message '+(isMe?'message-me':'message-other')});
elm.append($('<div>', {class: 'message-by'}).append(users[sender])); if(!no_name_message) {
if(sender == myinfo.kunjika)
elm.append($('<div>', {class: 'message-by'}).append('me'))
else
elm.append($('<div>', {class: 'message-by'}).append(vayaktiList[sender]+'('+sender+')'))
} else {
elm.addClass('siimple--py-1');
}
if(reply != null && reply.length > 0) { if(reply != null && reply.length > 0) {
elm.append( elm.append(
$('<div>', {class: 'message message-reply'}) $('<div>', {class: 'message message-reply'})
@ -159,35 +260,33 @@ function pushMessage(sender, text, reply = null) {
} }
elm.append($('<pre>').append(text)); elm.append($('<pre>').append(text));
elm.click(function() { elm.click(function() {
activateMessage(this); selectMessage(this);
}); });
area.append(elm); area.append(elm);
//to bottom
var scroll = $("#message_area_scroll"); var scroll = $("#message_area_scroll");
scroll.scrollTop(scroll[0].scrollHeight); scroll.scrollTop(scroll[0].scrollHeight);
} }
// in message area
function pushStatus(text) { function pushStatus(text) {
var area = $('#message_area'); var area = $('#message_area');
var elm = $('<div>', {class: 'status'}); var elm = $('<div>', {class: 'status'});
elm.append($('<span>', {class: 'siimple-tag siimple-tag--dark'}).append(text)); elm.append($('<span>', {class: 'siimple-tag siimple-tag--dark'}).append(text));
area.append(elm); area.append(elm);
//to bottom
var scroll = $("#message_area_scroll"); var scroll = $("#message_area_scroll");
scroll.scrollTop(scroll[0].scrollHeight); scroll.scrollTop(scroll[0].scrollHeight);
} }
function deactivateMessages() { function unselectMessages() {
$('.active').each(function() { $('.active').each(function() {
$(this).removeClass('active'); $(this).removeClass('active');
}); });
$('#selected_clip').addClass('hidden'); $('#selected_clip').addClass('hidden');
} }
function activateMessage(t) { function selectMessage(t) {
var t = $(t); var t = $(t);
t.toggleClass('active'); t.toggleClass('active');
@ -214,7 +313,7 @@ function prepareReply() {
el.removeClass('hidden'); el.removeClass('hidden');
el.attr('msg', text); el.attr('msg', text);
$('#reply_clip > span').text(text.substr(0, 15)+ '...'); $('#reply_clip > span').text(text.substr(0, 15)+ '...');
deactivateMessages(); unselectMessages();
} }
function send() { function send() {
@ -237,49 +336,22 @@ function copyMessagesToClipboard() {
$temp.val(selectedMessageToText()).select(); $temp.val(selectedMessageToText()).select();
document.execCommand("copy"); document.execCommand("copy");
$temp.remove(); $temp.remove();
deactivateMessages(); unselectMessages();
} }
function cleanMessage() { function cleanMessage() {
$('#message_area').empty(); $('#message_area').empty();
$('#action_clip').addClass('hidden'); $('#action_clip').addClass('hidden');
} }
// function wsend(p) {
// socket.send(p);
// }
// function join(r, l) { function vayaktiList() {
// socket.send(JSON.stringify({ var v = $('#vayakti_list');
// cmd: "join", v.empty();
// grih_kunjika: r, Object.keys(vayaktiList).forEach((key) => {
// length: l v.append($('<div>', {class: 'siimple-table-row'})
// })); .append($('<div>', {class: 'siimple-table-cell'}).append(key))
// } .append($('<div>', {class: 'siimple-table-cell'}).append(vayaktiList[key])));
});
// function leave() { $('#vayakti_model').removeClass('hidden');
// socket.send(JSON.stringify({ $('#action_clip').addClass('hidden');
// cmd: "leave" }
// }));
// }
// function send(t) {
// socket.send(JSON.stringify({
// cmd: "text",
// text: t
// }));
// }
// function info(k, n, t) {
// socket.send(JSON.stringify({
// cmd: "seinfo",
// kunjika: k,
// name: n,
// tags: t
// }));
// }
// function joinrand() {
// socket.send(JSON.stringify({
// cmd: "rand"
// }));
// }