mirror of https://github.com/PiyushXCoder/lupt.git
till dark mode
This commit is contained in:
parent
53e729ede8
commit
f102eec55c
|
|
@ -15,6 +15,7 @@ pub struct ChatPinnd {
|
||||||
|
|
||||||
pub struct Kaksh {
|
pub struct Kaksh {
|
||||||
length: Option<usize>,
|
length: Option<usize>,
|
||||||
|
last_message_id: u128,
|
||||||
loog: Vec<Loog>
|
loog: Vec<Loog>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,6 +96,7 @@ impl Handler<ms::JoinKaksh> for ChatPinnd {
|
||||||
});
|
});
|
||||||
self.kaksh.insert(msg.kaksh_kunjika, Kaksh {
|
self.kaksh.insert(msg.kaksh_kunjika, Kaksh {
|
||||||
length: msg.length,
|
length: msg.length,
|
||||||
|
last_message_id: 0,
|
||||||
loog: vec![Loog::new(msg.addr,msg.kunjika,msg.name, None)]
|
loog: vec![Loog::new(msg.addr,msg.kunjika,msg.name, None)]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -161,6 +163,7 @@ impl Handler<ms::JoinRandom> for ChatPinnd {
|
||||||
let group_kunjika = format!("gupt_{}>{}",msg.kunjika.to_owned(), vayakti_watchlist.kunjika);
|
let group_kunjika = format!("gupt_{}>{}",msg.kunjika.to_owned(), vayakti_watchlist.kunjika);
|
||||||
self.kaksh.insert(group_kunjika.to_owned(), Kaksh {
|
self.kaksh.insert(group_kunjika.to_owned(), Kaksh {
|
||||||
length: Some(2),
|
length: Some(2),
|
||||||
|
last_message_id: 0,
|
||||||
loog: vec![Loog::new(msg.addr.clone(), msg.kunjika.to_owned(), msg.name.to_owned(), Some(msg.tags.clone())),
|
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()))]
|
Loog::new(vayakti_watchlist.addr.clone(), vayakti_watchlist.kunjika.to_owned(), vayakti_watchlist.name.to_owned(), Some(vayakti_watchlist.tags.clone()))]
|
||||||
});
|
});
|
||||||
|
|
@ -266,6 +269,7 @@ impl Handler<ms::JoinRandomNext> for ChatPinnd {
|
||||||
}
|
}
|
||||||
self.kaksh.insert(group_kunjika.to_owned(), Kaksh {
|
self.kaksh.insert(group_kunjika.to_owned(), Kaksh {
|
||||||
length: Some(2),
|
length: Some(2),
|
||||||
|
last_message_id: 0,
|
||||||
loog: vec![Loog::new(addr.clone(), msg.kunjika.to_owned(), name.to_owned(), Some(tags.clone())),
|
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()))]
|
Loog::new(vayakti_watchlist.addr.clone(), vayakti_watchlist.kunjika.to_owned(), vayakti_watchlist.name.to_owned(), Some(vayakti_watchlist.tags.clone()))]
|
||||||
});
|
});
|
||||||
|
|
@ -291,12 +295,15 @@ impl Handler<ms::SendText> for ChatPinnd {
|
||||||
type Result = ();
|
type Result = ();
|
||||||
|
|
||||||
fn handle(&mut self, msg: ms::SendText, _: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: ms::SendText, _: &mut Self::Context) -> Self::Result {
|
||||||
if let Some(kaksh) = self.kaksh.get(&msg.kaksh_kunjika) {
|
if let Some(kaksh) = self.kaksh.get_mut(&msg.kaksh_kunjika) {
|
||||||
|
kaksh.last_message_id += 1;
|
||||||
|
let msg_id = kaksh.last_message_id;
|
||||||
kaksh.loog.iter().for_each(|c| {
|
kaksh.loog.iter().for_each(|c| {
|
||||||
c.addr.do_send(ms::WsText {
|
c.addr.do_send(ms::WsText {
|
||||||
sender_kunjika: msg.kunjika.to_owned(),
|
sender_kunjika: msg.kunjika.to_owned(),
|
||||||
text: msg.text.to_owned(),
|
text: msg.text.to_owned(),
|
||||||
reply: msg.reply.to_owned()
|
reply: msg.reply.to_owned(),
|
||||||
|
msg_id
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +35,7 @@ pub struct JoinRandomNext {
|
||||||
pub kunjika: String
|
pub kunjika: String
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request to send text t
|
/// Request to send text
|
||||||
#[derive(Clone, Message)]
|
#[derive(Clone, Message)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
pub struct SendText {
|
pub struct SendText {
|
||||||
|
|
@ -44,6 +44,15 @@ pub struct SendText {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub reply: Option<String>,
|
pub reply: Option<String>,
|
||||||
}
|
}
|
||||||
|
/// Request to send image t
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct SendImage {
|
||||||
|
pub kaksh_kunjika: String,
|
||||||
|
pub kunjika: String,
|
||||||
|
pub part: String,
|
||||||
|
pub image_id: i32
|
||||||
|
}
|
||||||
|
|
||||||
// Request to send text t
|
// Request to send text t
|
||||||
#[derive(Clone, Message)]
|
#[derive(Clone, Message)]
|
||||||
|
|
@ -81,6 +90,15 @@ pub struct WsKunjikaHash {
|
||||||
#[derive(Clone, Message)]
|
#[derive(Clone, Message)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
pub struct WsText {
|
pub struct WsText {
|
||||||
|
pub text: String,
|
||||||
|
pub reply: Option<String>,
|
||||||
|
pub sender_kunjika: String,
|
||||||
|
pub msg_id: u128
|
||||||
|
}
|
||||||
|
// Request to send transfer text
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsImage {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub reply: Option<String>,
|
pub reply: Option<String>,
|
||||||
pub sender_kunjika: String
|
pub sender_kunjika: String
|
||||||
|
|
@ -76,7 +76,8 @@ impl Handler<ms::WsText> for WsSansad {
|
||||||
"cmd": "text",
|
"cmd": "text",
|
||||||
"text": msg.text,
|
"text": msg.text,
|
||||||
"reply": msg.reply,
|
"reply": msg.reply,
|
||||||
"kunjika": msg.sender_kunjika // Sender's kunjuka
|
"kunjika": msg.sender_kunjika, // Sender's kunjuka
|
||||||
|
"msg_id": msg.msg_id.to_string()
|
||||||
});
|
});
|
||||||
ctx.text(json.to_string());
|
ctx.text(json.to_string());
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
use actix::prelude::*;
|
||||||
|
use dev::{MessageResponse, ResponseChannel};
|
||||||
|
use crate::ws_sansad::WsSansad;
|
||||||
|
|
||||||
|
pub mod pind;
|
||||||
|
pub mod sansad;
|
||||||
|
pub mod util;
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
//! Messages to be sent between Actors
|
||||||
|
use super::*;
|
||||||
|
use super::util::Resp;
|
||||||
|
|
||||||
|
//################################################## For ChatPinnd ##################################################
|
||||||
|
/// Request to change information of vayakti to list of vayakti im ChatPind
|
||||||
|
|
||||||
|
/// Request to Kaksh with its kunjika
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "Resp")]
|
||||||
|
pub struct JoinKaksh {
|
||||||
|
pub kaksh_kunjika: String,
|
||||||
|
pub length: Option<usize>,
|
||||||
|
pub addr: Addr<WsSansad>,
|
||||||
|
pub kunjika: String,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request to connect Random vayakti
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "Resp")]
|
||||||
|
pub struct JoinRandom {
|
||||||
|
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 kaksh_kunjika: String,
|
||||||
|
pub kunjika: String
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request to send text
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct SendText {
|
||||||
|
pub kaksh_kunjika: String,
|
||||||
|
pub kunjika: String,
|
||||||
|
pub text: String,
|
||||||
|
pub reply: Option<String>,
|
||||||
|
}
|
||||||
|
/// Request to send image t
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct SendImage {
|
||||||
|
pub kaksh_kunjika: String,
|
||||||
|
pub kunjika: String,
|
||||||
|
pub part: String,
|
||||||
|
pub image_id: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to send text t
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct SendStatus {
|
||||||
|
pub kaksh_kunjika: String,
|
||||||
|
pub kunjika: String,
|
||||||
|
pub status: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to send text t
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "String")]
|
||||||
|
pub struct List {
|
||||||
|
pub kaksh_kunjika: String
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request to leave kaksh
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct LeaveUser {
|
||||||
|
pub kaksh_kunjika: Option<String>,
|
||||||
|
pub kunjika: String,
|
||||||
|
pub addr: Addr<WsSansad>
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
//################################################## For WsSansad ##################################################
|
||||||
|
// Request to send own kunjika hash
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsKunjikaHash {
|
||||||
|
pub kunjika: String
|
||||||
|
}
|
||||||
|
// Request to send transfer text
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsText {
|
||||||
|
pub text: String,
|
||||||
|
pub reply: Option<String>,
|
||||||
|
pub sender_kunjika: String,
|
||||||
|
pub msg_id: u128
|
||||||
|
}
|
||||||
|
// Request to send transfer text
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsImage {
|
||||||
|
pub text: String,
|
||||||
|
pub reply: Option<String>,
|
||||||
|
pub sender_kunjika: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to send transfer text
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsStatus {
|
||||||
|
pub status: String,
|
||||||
|
pub sender_kunjika: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request to send transfer text
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsList {
|
||||||
|
pub json: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify Someone connected
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsConnected {
|
||||||
|
pub name: String,
|
||||||
|
pub kunjika: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify someone disconnected
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsDisconnected {
|
||||||
|
pub kunjika: String,
|
||||||
|
pub name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give response message
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsResponse {
|
||||||
|
pub result: String,
|
||||||
|
pub message: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Got connected to random vayakti
|
||||||
|
#[derive(Clone, Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct WsConnectedRandom {
|
||||||
|
pub name: String,
|
||||||
|
pub kunjika: String,
|
||||||
|
pub kaksh_kunjika: String
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
//################################################## Helper ##################################################
|
||||||
|
#[derive(Debug)]
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// send text to everyone
|
||||||
|
impl Handler<ms::pind::SendText> for ChatPinnd {
|
||||||
|
type Result = ();
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: ms::pind::SendText, _: &mut Self::Context) -> Self::Result {
|
||||||
|
if let Some(kaksh) = self.kaksh.get_mut(&msg.kaksh_kunjika) {
|
||||||
|
kaksh.last_message_id += 1;
|
||||||
|
let msg_id = kaksh.last_message_id;
|
||||||
|
kaksh.loog.iter().for_each(|c| {
|
||||||
|
c.addr.do_send(ms::sansad::WsText {
|
||||||
|
sender_kunjika: msg.kunjika.to_owned(),
|
||||||
|
text: msg.text.to_owned(),
|
||||||
|
reply: msg.reply.to_owned(),
|
||||||
|
msg_id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// send status to everyone
|
||||||
|
impl Handler<ms::pind::SendStatus> for ChatPinnd {
|
||||||
|
type Result = ();
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: ms::pind::SendStatus, _: &mut Self::Context) -> Self::Result {
|
||||||
|
if let Some(kaksh) = self.kaksh.get(&msg.kaksh_kunjika) {
|
||||||
|
kaksh.loog.iter().for_each(|c| {
|
||||||
|
if c.kunjika == msg.kunjika {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
c.addr.do_send(ms::sansad::WsStatus {
|
||||||
|
sender_kunjika: msg.kunjika.to_owned(),
|
||||||
|
status: msg.status.to_owned(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
//! Chat Pinnd(पिण्ड) is Actor to manage Websocket Chat related action
|
||||||
|
|
||||||
|
mod user;
|
||||||
|
mod message;
|
||||||
|
|
||||||
|
use std::{collections::HashMap, vec};
|
||||||
|
|
||||||
|
use actix::prelude::*;
|
||||||
|
use actix_broker::BrokerSubscribe;
|
||||||
|
|
||||||
|
use crate::{ws_sansad, broker_messages as ms, broker_messages::util::Resp};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct ChatPinnd {
|
||||||
|
kaksh: HashMap<String, Kaksh>, // kunjika, Kaksh
|
||||||
|
vyaktigat_waitlist: Vec<VyaktiWatchlist>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Kaksh {
|
||||||
|
length: Option<usize>,
|
||||||
|
last_message_id: u128,
|
||||||
|
loog: Vec<Loog>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Loog {
|
||||||
|
addr: Addr<ws_sansad::WsSansad>,
|
||||||
|
kunjika: String,
|
||||||
|
name: String,
|
||||||
|
tags: Option<Vec<String>>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Vyakti {
|
||||||
|
name: String,
|
||||||
|
tags: Vec<String>
|
||||||
|
}
|
||||||
|
pub struct VyaktiWatchlist {
|
||||||
|
kunjika: String,
|
||||||
|
name: String,
|
||||||
|
tags: Vec<String>,
|
||||||
|
addr: Addr<ws_sansad::WsSansad>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for ChatPinnd {
|
||||||
|
type Context = Context<Self>;
|
||||||
|
|
||||||
|
fn started(&mut self, ctx: &mut Self::Context) {
|
||||||
|
// for actix broker
|
||||||
|
self.subscribe_system_async::<ms::pind::SendText>(ctx);
|
||||||
|
self.subscribe_system_async::<ms::pind::SendStatus>(ctx);
|
||||||
|
self.subscribe_system_async::<ms::pind::LeaveUser>(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Default for ChatPinnd {
|
||||||
|
fn default() -> Self {
|
||||||
|
ChatPinnd {
|
||||||
|
kaksh: HashMap::new(),
|
||||||
|
vyaktigat_waitlist: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Loog {
|
||||||
|
fn new(addr: Addr<ws_sansad::WsSansad>,
|
||||||
|
kunjika: String,
|
||||||
|
name: String,
|
||||||
|
tags: Option<Vec<String>>) -> Self {
|
||||||
|
|
||||||
|
Loog {
|
||||||
|
addr,
|
||||||
|
kunjika,
|
||||||
|
name,
|
||||||
|
tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SystemService for ChatPinnd {}
|
||||||
|
impl Supervised for ChatPinnd {}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,290 @@
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// Join kaksh
|
||||||
|
impl Handler<ms::pind::JoinKaksh> for ChatPinnd {
|
||||||
|
type Result = Resp;
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: ms::pind::JoinKaksh, _: &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.kaksh.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 kaksh exist and add user
|
||||||
|
match self.kaksh.get_mut(&msg.kaksh_kunjika) {
|
||||||
|
Some(kaksh) =>{ // exist
|
||||||
|
// check if kaksh have no space left
|
||||||
|
if let Some(n) = kaksh.length {
|
||||||
|
if kaksh.loog.len() >= n {
|
||||||
|
return Resp::Err("Kaksh have no space".to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kaksh.loog.iter().for_each(|a: &Loog| {
|
||||||
|
a.addr.do_send(ms::sansad::WsConnected {
|
||||||
|
name: msg.name.to_owned(),
|
||||||
|
kunjika: msg.kunjika.to_owned()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
kaksh.loog.push(Loog::new(msg.addr, msg.kunjika,msg.name, None));
|
||||||
|
|
||||||
|
|
||||||
|
}, None => { // don't exist
|
||||||
|
// add kaksh and notify
|
||||||
|
msg.addr.do_send(ms::sansad::WsConnected {
|
||||||
|
name: msg.name.to_owned(),
|
||||||
|
kunjika: msg.kunjika.to_owned()
|
||||||
|
});
|
||||||
|
self.kaksh.insert(msg.kaksh_kunjika, Kaksh {
|
||||||
|
length: msg.length,
|
||||||
|
last_message_id: 0,
|
||||||
|
loog: vec![Loog::new(msg.addr,msg.kunjika,msg.name, None)]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Resp::Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Join random vayakti
|
||||||
|
/// Works as:
|
||||||
|
/// Check if watchlist is empty, if yes add the kunjika andaddr to watchlist
|
||||||
|
/// if watchlist have people get 0th person an connect it
|
||||||
|
impl Handler<ms::pind::JoinRandom> for ChatPinnd {
|
||||||
|
type Result = Resp;
|
||||||
|
fn handle(&mut self, msg: ms::pind::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.kaksh.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
|
||||||
|
if self.vyaktigat_waitlist.len() == 0 {
|
||||||
|
self.vyaktigat_waitlist.push(VyaktiWatchlist {
|
||||||
|
kunjika: msg.kunjika,
|
||||||
|
addr: msg.addr,
|
||||||
|
name: msg.name,
|
||||||
|
tags: msg.tags
|
||||||
|
});
|
||||||
|
return Resp::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect person with tag
|
||||||
|
let pos = if msg.tags.len() > 0 {
|
||||||
|
match self.vyaktigat_waitlist.iter().position(|vk| {
|
||||||
|
match vk.tags.iter().position(|t| msg.tags.contains(t)) {
|
||||||
|
Some(_) => true,
|
||||||
|
None => false
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Some(i) => i,
|
||||||
|
None => {
|
||||||
|
self.vyaktigat_waitlist.push(VyaktiWatchlist {
|
||||||
|
kunjika: msg.kunjika,
|
||||||
|
addr: msg.addr,
|
||||||
|
name: msg.name,
|
||||||
|
tags: msg.tags
|
||||||
|
});
|
||||||
|
return Resp::None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { 0 };
|
||||||
|
|
||||||
|
let vayakti_watchlist = self.vyaktigat_waitlist.remove(pos);
|
||||||
|
let group_kunjika = format!("gupt_{}>{}",msg.kunjika.to_owned(), vayakti_watchlist.kunjika);
|
||||||
|
self.kaksh.insert(group_kunjika.to_owned(), Kaksh {
|
||||||
|
length: Some(2),
|
||||||
|
last_message_id: 0,
|
||||||
|
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
|
||||||
|
msg.addr.do_send(ms::sansad::WsConnectedRandom {
|
||||||
|
name: vayakti_watchlist.name,
|
||||||
|
kunjika: vayakti_watchlist.kunjika,
|
||||||
|
kaksh_kunjika: group_kunjika.to_owned()
|
||||||
|
});
|
||||||
|
vayakti_watchlist.addr.do_send(ms::sansad::WsConnectedRandom {
|
||||||
|
name: msg.name,
|
||||||
|
kunjika: msg.kunjika.to_owned(),
|
||||||
|
kaksh_kunjika: group_kunjika
|
||||||
|
});
|
||||||
|
|
||||||
|
Resp::Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Next Random user
|
||||||
|
impl Handler<ms::pind::JoinRandomNext> for ChatPinnd {
|
||||||
|
type Result = Resp;
|
||||||
|
fn handle(&mut self, msg: ms::pind::JoinRandomNext, _: &mut Self::Context) -> Self::Result {
|
||||||
|
let kaksh = match self.kaksh.get_mut(&msg.kaksh_kunjika) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return Resp::Err("Failed to join, check entries!".to_owned())
|
||||||
|
};
|
||||||
|
|
||||||
|
let loog_i = match kaksh.loog.iter().position(|a| a.kunjika == msg.kunjika) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return Resp::Err("Failed to join, check entries!".to_owned())
|
||||||
|
};
|
||||||
|
|
||||||
|
let addr;
|
||||||
|
let name;
|
||||||
|
let tags;
|
||||||
|
|
||||||
|
{
|
||||||
|
let loog = match kaksh.loog.get(loog_i) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return Resp::Err("Failed to join, check entries!".to_owned())
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = match loog.tags.clone() {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return Resp::Err("Failed to join, check entries!".to_owned())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from old kaksh
|
||||||
|
kaksh.loog.remove(loog_i);
|
||||||
|
kaksh.loog.iter().for_each(|a| {
|
||||||
|
a.addr.do_send(ms::sansad::WsDisconnected {
|
||||||
|
kunjika: msg.kunjika.to_owned(),
|
||||||
|
name: name.to_owned()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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 pos = if tags.len() > 0 {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { 0 };
|
||||||
|
let vayakti_watchlist = self.vyaktigat_waitlist.remove(pos);
|
||||||
|
let group_kunjika = format!("gupt_{}>{}",msg.kunjika.to_owned(), vayakti_watchlist.kunjika);
|
||||||
|
|
||||||
|
let log_count = kaksh.loog.len();
|
||||||
|
drop(kaksh);
|
||||||
|
if log_count == 0 {
|
||||||
|
self.kaksh.remove(&msg.kaksh_kunjika);
|
||||||
|
}
|
||||||
|
self.kaksh.insert(group_kunjika.to_owned(), Kaksh {
|
||||||
|
length: Some(2),
|
||||||
|
last_message_id: 0,
|
||||||
|
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::sansad::WsConnectedRandom {
|
||||||
|
name: vayakti_watchlist.name,
|
||||||
|
kunjika: vayakti_watchlist.kunjika,
|
||||||
|
kaksh_kunjika: group_kunjika.to_owned()
|
||||||
|
});
|
||||||
|
|
||||||
|
vayakti_watchlist.addr.do_send(ms::sansad::WsConnectedRandom {
|
||||||
|
name,
|
||||||
|
kunjika: msg.kunjika.to_owned(),
|
||||||
|
kaksh_kunjika: group_kunjika
|
||||||
|
});
|
||||||
|
|
||||||
|
Resp::Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// send list of users
|
||||||
|
impl Handler<ms::pind::List> for ChatPinnd {
|
||||||
|
type Result = String;
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: ms::pind::List, _: &mut Self::Context) -> Self::Result {
|
||||||
|
if let Some(kaksh) = self.kaksh.get(&msg.kaksh_kunjika) {
|
||||||
|
let mut list = Vec::new();
|
||||||
|
for x in kaksh.loog.iter() {
|
||||||
|
list.push((x.kunjika.to_owned(),x.name.to_owned()));
|
||||||
|
}
|
||||||
|
serde_json::json!(list).to_string()
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Notifiy a user disconnected and trim kaksh
|
||||||
|
impl Handler<ms::pind::LeaveUser> for ChatPinnd {
|
||||||
|
type Result = ();
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: ms::pind::LeaveUser, _: &mut Self::Context) -> Self::Result {
|
||||||
|
if let Some(kaksh_kunjika) = &msg.kaksh_kunjika {
|
||||||
|
if let Some(kaksh) = self.kaksh.get_mut(kaksh_kunjika) {
|
||||||
|
let name = if let Some(i) = kaksh.loog.iter().position(|x| x.addr == msg.addr) {
|
||||||
|
kaksh.loog.remove(i).name
|
||||||
|
} else { "".to_owned() };
|
||||||
|
|
||||||
|
if kaksh.loog.len() == 0 {
|
||||||
|
self.kaksh.remove(kaksh_kunjika);
|
||||||
|
} else {
|
||||||
|
kaksh.loog.iter().for_each(|a| {
|
||||||
|
a.addr.do_send(ms::sansad::WsDisconnected {
|
||||||
|
kunjika: msg.kunjika.to_owned(),
|
||||||
|
name: name.to_owned()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(i) = self.vyaktigat_waitlist.iter().position(|a| a.kunjika == msg.kunjika) {
|
||||||
|
self.vyaktigat_waitlist.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,7 @@ use ws_sansad::WsSansad;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod messages;
|
mod broker_messages;
|
||||||
mod ws_sansad;
|
mod ws_sansad;
|
||||||
mod chat_pinnd;
|
mod chat_pinnd;
|
||||||
mod validator;
|
mod validator;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// send text message
|
||||||
|
impl Handler<ms::sansad::WsText> for WsSansad {
|
||||||
|
type Result = ();
|
||||||
|
fn handle(&mut self, msg: ms::sansad::WsText, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let json = json!({
|
||||||
|
"cmd": "text",
|
||||||
|
"text": msg.text,
|
||||||
|
"reply": msg.reply,
|
||||||
|
"kunjika": msg.sender_kunjika, // Sender's kunjuka
|
||||||
|
"msg_id": msg.msg_id.to_string()
|
||||||
|
});
|
||||||
|
ctx.text(json.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// send text status
|
||||||
|
impl Handler<ms::sansad::WsStatus> for WsSansad {
|
||||||
|
type Result = ();
|
||||||
|
fn handle(&mut self, msg: ms::sansad::WsStatus, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let json = json!({
|
||||||
|
"cmd": "status",
|
||||||
|
"status": msg.status,
|
||||||
|
"kunjika": msg.sender_kunjika // Sender's kunjuka
|
||||||
|
});
|
||||||
|
ctx.text(json.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// List Vayakti
|
||||||
|
impl Handler<ms::sansad::WsList> for WsSansad {
|
||||||
|
type Result = ();
|
||||||
|
fn handle(&mut self, msg: ms::sansad::WsList, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let json = json!({
|
||||||
|
"cmd": "list",
|
||||||
|
"vayakti": msg.json
|
||||||
|
});
|
||||||
|
ctx.text(json.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Own Kunjika hash
|
||||||
|
impl Handler<ms::sansad::WsKunjikaHash> for WsSansad {
|
||||||
|
type Result = ();
|
||||||
|
fn handle(&mut self, msg: ms::sansad::WsKunjikaHash, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let json = json!({
|
||||||
|
"cmd": "kunjika",
|
||||||
|
"kunjika": msg.kunjika
|
||||||
|
});
|
||||||
|
ctx.text(json.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// send response ok, error
|
||||||
|
impl Handler<ms::sansad::WsResponse> for WsSansad {
|
||||||
|
type Result = ();
|
||||||
|
fn handle(&mut self, msg: ms::sansad::WsResponse, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let json = json!({
|
||||||
|
"cmd": "resp",
|
||||||
|
"result": msg.result,
|
||||||
|
"message": msg.message
|
||||||
|
});
|
||||||
|
ctx.text(json.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// notify someone got connected
|
||||||
|
impl Handler<ms::sansad::WsConnected> for WsSansad {
|
||||||
|
type Result = ();
|
||||||
|
fn handle(&mut self, msg: ms::sansad::WsConnected, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let json = json!({
|
||||||
|
"cmd": "connected",
|
||||||
|
"name": msg.name,
|
||||||
|
"kunjika": msg.kunjika
|
||||||
|
});
|
||||||
|
ctx.text(json.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// notify someone got disconnected
|
||||||
|
impl Handler<ms::sansad::WsDisconnected> for WsSansad {
|
||||||
|
type Result = ();
|
||||||
|
fn handle(&mut self, msg: ms::sansad::WsDisconnected, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let json = json!({
|
||||||
|
"cmd": "disconnected",
|
||||||
|
"name": msg.name,
|
||||||
|
"kunjika": msg.kunjika
|
||||||
|
});
|
||||||
|
ctx.text(json.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// notify got connected to random person
|
||||||
|
impl Handler<ms::sansad::WsConnectedRandom> for WsSansad {
|
||||||
|
type Result = ();
|
||||||
|
fn handle(&mut self, msg: ms::sansad::WsConnectedRandom, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
self.isthiti = Isthiti::Kaksh(msg.kaksh_kunjika);
|
||||||
|
let json = json!({
|
||||||
|
"cmd": "random",
|
||||||
|
"name": msg.name,
|
||||||
|
"kunjika": msg.kunjika
|
||||||
|
});
|
||||||
|
ctx.text(json.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl WsSansad {
|
||||||
|
|
||||||
|
/// send text to vayakti in kaksh
|
||||||
|
pub async fn send_text(&mut self, val: Value) {
|
||||||
|
// check if vayakti exist
|
||||||
|
if let Isthiti::None = self.isthiti {
|
||||||
|
self.send_err_response("Not in any Kaksh");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if connected to any kaksh
|
||||||
|
match self.isthiti {
|
||||||
|
Isthiti::Kaksh(_) => (),
|
||||||
|
_ => {
|
||||||
|
self.send_err_response("Kaksh not connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sent text
|
||||||
|
let text = match val.get("text") {
|
||||||
|
Some(val) => val,
|
||||||
|
None => {
|
||||||
|
self.send_err_response("Invalid request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}.as_str().unwrap().to_owned();
|
||||||
|
|
||||||
|
let reply: Option<String> = match val.get("reply") {
|
||||||
|
Some(val) => Some(val.as_str().unwrap().to_owned()),
|
||||||
|
None => None
|
||||||
|
};
|
||||||
|
|
||||||
|
let kaksh_kunjika = match &self.isthiti {
|
||||||
|
Isthiti::Kaksh(kaksh_kunjika) => {
|
||||||
|
kaksh_kunjika.to_owned()
|
||||||
|
}, _ => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Broker::<SystemBroker>::issue_async(ms::pind::SendText {
|
||||||
|
kaksh_kunjika,
|
||||||
|
kunjika: self.kunjika.to_owned(),
|
||||||
|
text,
|
||||||
|
reply
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// send status to vayakti in kaksh
|
||||||
|
pub async fn send_status(&mut self, val: Value) {
|
||||||
|
// check if vayakti exist
|
||||||
|
if let Isthiti::None = self.isthiti {
|
||||||
|
self.send_err_response("Not in any Kaksh");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if connected to any kaksh
|
||||||
|
match self.isthiti {
|
||||||
|
Isthiti::Kaksh(_) => (),
|
||||||
|
_ => {
|
||||||
|
self.send_err_response("Kaksh not connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sent status
|
||||||
|
let status = match val.get("status") {
|
||||||
|
Some(val) => val,
|
||||||
|
None => {
|
||||||
|
self.send_err_response("Invalid request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}.as_str().unwrap().to_owned();
|
||||||
|
let kaksh_kunjika = match &self.isthiti {
|
||||||
|
Isthiti::Kaksh(kaksh_kunjika) => {
|
||||||
|
kaksh_kunjika.to_owned()
|
||||||
|
}, _ => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Broker::<SystemBroker>::issue_async(ms::pind::SendStatus {
|
||||||
|
kaksh_kunjika,
|
||||||
|
kunjika: self.kunjika.to_owned(),
|
||||||
|
status
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
//! Ws Sansad manage websocket of each client
|
||||||
|
|
||||||
|
mod handlers;
|
||||||
|
mod users;
|
||||||
|
mod messages;
|
||||||
|
|
||||||
|
use actix::prelude::*;
|
||||||
|
use actix_broker::{Broker, SystemBroker};
|
||||||
|
use actix_web_actors::ws;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
use crate::{chat_pinnd::ChatPinnd, broker_messages as ms, broker_messages::util::Resp, validator::{Validation as vl, validate}};
|
||||||
|
|
||||||
|
/// 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(15);
|
||||||
|
|
||||||
|
pub struct WsSansad {
|
||||||
|
kunjika: String,
|
||||||
|
isthiti: Isthiti,
|
||||||
|
addr: Option<Addr<Self>>,
|
||||||
|
hb: Instant
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Isthiti {
|
||||||
|
None,
|
||||||
|
Kaksh(String),
|
||||||
|
VraktigatWaitlist
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Actor for WsSansad {
|
||||||
|
type Context = ws::WebsocketContext<Self>;
|
||||||
|
|
||||||
|
fn started(&mut self, ctx: &mut Self::Context) {
|
||||||
|
self.addr = Some(ctx.address().clone()); // own addr
|
||||||
|
self.hb(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stopping(&mut self, _: &mut Self::Context) -> Running {
|
||||||
|
futures::executor::block_on(self.leave_kaksh()); // notify leaving
|
||||||
|
Running::Stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// manage stream
|
||||||
|
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsSansad {
|
||||||
|
fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
|
||||||
|
match msg {
|
||||||
|
Ok(ws::Message::Ping(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));
|
||||||
|
}, Ok(ws::Message::Close(msg)) => {
|
||||||
|
ctx.close(msg);
|
||||||
|
ctx.stop();
|
||||||
|
}
|
||||||
|
_ => ctx.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl WsSansad {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
WsSansad {
|
||||||
|
kunjika: String::new(),
|
||||||
|
isthiti: Isthiti::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
|
||||||
|
|
||||||
|
// stop actor
|
||||||
|
futures::executor::block_on(act.leave_kaksh()); // notify leaving
|
||||||
|
ctx.stop();
|
||||||
|
// don't try to send a ping
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.ping(b"");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// parse the request text from client
|
||||||
|
async fn parse_text_handle(&mut self, msg: String) {
|
||||||
|
if let Ok(val) = serde_json::from_str::<Value>(&msg) {
|
||||||
|
// let cmd = match val.get("cmd") {
|
||||||
|
// Some(v) => v,
|
||||||
|
// None => return
|
||||||
|
// };
|
||||||
|
// let cmd = match cmd.as_str() {
|
||||||
|
// Some(v) => v,
|
||||||
|
// None => return
|
||||||
|
// };
|
||||||
|
|
||||||
|
match val.get("cmd").unwrap().as_str().unwrap() {
|
||||||
|
"join" => { self.join_kaksh(val).await },
|
||||||
|
"rand" => { self.join_random(val).await },
|
||||||
|
"randnext" => { self.join_random_next().await },
|
||||||
|
"text" => { self.send_text(val).await },
|
||||||
|
"status" => { self.send_status(val).await },
|
||||||
|
"list" => { self.list().await },
|
||||||
|
"leave" => { self.leave_kaksh().await },
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// send ok response
|
||||||
|
fn send_ok_response(&self, text: &str) {
|
||||||
|
self.addr.clone().unwrap().do_send(ms::sansad::WsResponse {
|
||||||
|
result: "Ok".to_owned(),
|
||||||
|
message: text.to_owned()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// send error response
|
||||||
|
fn send_err_response(&self, text: &str) {
|
||||||
|
self.addr.clone().unwrap().do_send(ms::sansad::WsResponse {
|
||||||
|
result: "Err".to_owned(),
|
||||||
|
message: text.to_owned()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,244 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl WsSansad {
|
||||||
|
/// Request for joining to random person
|
||||||
|
pub 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::Kaksh(_) => return
|
||||||
|
}
|
||||||
|
|
||||||
|
let kunjika = match val.get("kunjika") {
|
||||||
|
Some(val ) => val.as_str().unwrap().to_owned(),
|
||||||
|
None => {
|
||||||
|
self.send_err_response("Invalid request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// kunjika to hash
|
||||||
|
let mut m = sha1::Sha1::new();
|
||||||
|
m.update(format!("{}{}",kunjika,
|
||||||
|
std::env::var("SALT").unwrap_or("".to_owned())).as_bytes());
|
||||||
|
let kunjika = m.digest().to_string();
|
||||||
|
|
||||||
|
let name = match val.get("name") {
|
||||||
|
Some(val ) => val.as_str().unwrap().to_owned(),
|
||||||
|
None => {
|
||||||
|
self.send_err_response("Invalid request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let tags = match val.get("tags") {
|
||||||
|
Some(val ) => {
|
||||||
|
let mut v = Vec::new();
|
||||||
|
for x in val.as_str().unwrap().split_ascii_whitespace() {
|
||||||
|
v.push(x.to_owned());
|
||||||
|
}
|
||||||
|
v
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
if let Some(val ) = validate(vec![vl::NonEmpty, vl::NoSpace, vl::NoHashtag], &kunjika, "Kunjika") {
|
||||||
|
self.send_err_response(&val);
|
||||||
|
return;
|
||||||
|
} else if let Some(val ) = validate(vec![vl::NonEmpty], &name, "Name") {
|
||||||
|
self.send_err_response(&val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// request
|
||||||
|
let result: Resp = ChatPinnd::from_registry().send(ms::pind::JoinRandom{
|
||||||
|
addr: self.addr.clone().unwrap(),
|
||||||
|
kunjika: kunjika.to_owned(),
|
||||||
|
name,
|
||||||
|
tags
|
||||||
|
}).await.unwrap();
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Resp::Err(err) => self.send_err_response(&err),
|
||||||
|
Resp::Ok => {
|
||||||
|
self.addr.clone().unwrap().do_send(ms::sansad::WsKunjikaHash{ kunjika: kunjika.clone() });
|
||||||
|
self.kunjika = kunjika;
|
||||||
|
},
|
||||||
|
Resp::None => {
|
||||||
|
self.addr.clone().unwrap().do_send(ms::sansad::WsResponse{
|
||||||
|
result: "watch".to_owned() ,
|
||||||
|
message: "Watchlist".to_owned()
|
||||||
|
});
|
||||||
|
self.isthiti = Isthiti::VraktigatWaitlist;
|
||||||
|
self.addr.clone().unwrap().do_send(ms::sansad::WsKunjikaHash{ kunjika: kunjika.clone() });
|
||||||
|
self.kunjika = kunjika
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request for joining to random person
|
||||||
|
pub async fn join_random_next(&mut self) {
|
||||||
|
// Check is already joined
|
||||||
|
let kaksh_kunjika = match &self.isthiti {
|
||||||
|
Isthiti::VraktigatWaitlist => {
|
||||||
|
self.send_ok_response("watchlist");
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
Isthiti::Kaksh(kaksh_kunjika) => kaksh_kunjika,
|
||||||
|
Isthiti::None => {
|
||||||
|
self.send_ok_response("Not allowed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// request
|
||||||
|
let result: Resp = ChatPinnd::from_registry().send(ms::pind::JoinRandomNext {
|
||||||
|
kunjika: self.kunjika.to_owned(),
|
||||||
|
kaksh_kunjika: kaksh_kunjika.to_owned(),
|
||||||
|
}).await.unwrap();
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Resp::Err(err) => self.send_err_response(&err),
|
||||||
|
Resp::None => {
|
||||||
|
self.addr.clone().unwrap().do_send(ms::sansad::WsResponse{
|
||||||
|
result: "watch".to_owned() ,
|
||||||
|
message: "Watchlist".to_owned()
|
||||||
|
});
|
||||||
|
self.isthiti = Isthiti::VraktigatWaitlist;
|
||||||
|
self.kunjika = self.kunjika.to_owned()
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request to join to kaksh
|
||||||
|
pub async fn join_kaksh(&mut self, val: Value) {
|
||||||
|
// Check is already joined
|
||||||
|
match self.isthiti {
|
||||||
|
Isthiti::None => (),
|
||||||
|
_ => return
|
||||||
|
}
|
||||||
|
|
||||||
|
// is vayakti in watch list
|
||||||
|
if let Isthiti::VraktigatWaitlist = self.isthiti {
|
||||||
|
self.send_ok_response("watchlist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let kunjika = match val.get("kunjika") {
|
||||||
|
Some(val ) => val.as_str().unwrap().to_owned(),
|
||||||
|
None => {
|
||||||
|
self.send_err_response("Invalid request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// kunjika to hash
|
||||||
|
let mut m = sha1::Sha1::new();
|
||||||
|
m.update(format!("{}{}",kunjika,
|
||||||
|
std::env::var("SALT").unwrap_or("".to_owned())).as_bytes());
|
||||||
|
let kunjika = m.digest().to_string();
|
||||||
|
|
||||||
|
let name = match val.get("name") {
|
||||||
|
Some(val ) => val.as_str().unwrap().to_owned(),
|
||||||
|
None => {
|
||||||
|
self.send_err_response("Invalid request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let kaksh_kunjika = match val.get("kaksh_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") {
|
||||||
|
Some(val) => match val.as_i64(){
|
||||||
|
Some(val) => Some(val as usize),
|
||||||
|
None => None
|
||||||
|
},
|
||||||
|
None => None
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
if let Some(val ) = validate(vec![vl::NonEmpty, vl::NoGupt, vl::NoSpace], &kaksh_kunjika, "Kaksh Kunjika") {
|
||||||
|
self.send_err_response(&val);
|
||||||
|
return;
|
||||||
|
} else if let Some(val ) = validate(vec![vl::NonEmpty, vl::NoSpace, vl::NoHashtag], &kunjika, "Kunjika") {
|
||||||
|
self.send_err_response(&val);
|
||||||
|
return;
|
||||||
|
} else if let Some(val ) = validate(vec![vl::NonEmpty], &name, "Name") {
|
||||||
|
self.send_err_response(&val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// request
|
||||||
|
let result: Resp = ChatPinnd::from_registry().send(ms::pind::JoinKaksh {
|
||||||
|
kaksh_kunjika: kaksh_kunjika.to_owned(),
|
||||||
|
length,
|
||||||
|
addr: self.addr.clone().unwrap(),
|
||||||
|
kunjika: kunjika.to_owned(),
|
||||||
|
name
|
||||||
|
}).await.unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Resp::Err(err) => self.send_err_response(&err),
|
||||||
|
Resp::Ok => {
|
||||||
|
self.isthiti = Isthiti::Kaksh(kaksh_kunjika);
|
||||||
|
self.addr.clone().unwrap().do_send(ms::sansad::WsKunjikaHash{ kunjika: kunjika.clone() });
|
||||||
|
self.kunjika = kunjika;
|
||||||
|
self.send_ok_response("joined")
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request to join to kaksh
|
||||||
|
pub async fn list(&mut self) {
|
||||||
|
// check if vayakti exist
|
||||||
|
if let Isthiti::None = self.isthiti {
|
||||||
|
self.send_err_response("Not in any Kaksh");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if connected to any kaksh
|
||||||
|
match &self.isthiti {
|
||||||
|
Isthiti::Kaksh(kunjika) => {
|
||||||
|
let json: String = ChatPinnd::from_registry().send(ms::pind::List {
|
||||||
|
kaksh_kunjika: kunjika.to_owned()
|
||||||
|
}).await.unwrap();
|
||||||
|
|
||||||
|
self.addr.clone().unwrap().do_send(ms::sansad::WsList {
|
||||||
|
json
|
||||||
|
})
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
self.send_err_response("Kaksh not connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// notify leaving
|
||||||
|
pub async fn leave_kaksh(&mut self) {
|
||||||
|
let kaksh_kunjika = match &self.isthiti {
|
||||||
|
Isthiti::Kaksh(val) => Some(val.to_owned()),
|
||||||
|
_ => None
|
||||||
|
};
|
||||||
|
|
||||||
|
Broker::<SystemBroker>::issue_async(ms::pind::LeaveUser {
|
||||||
|
kaksh_kunjika,
|
||||||
|
kunjika: self.kunjika.to_owned(),
|
||||||
|
addr: self.addr.clone().unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
self.isthiti = Isthiti::None;
|
||||||
|
self.send_ok_response("left");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,8 +9,10 @@
|
||||||
:root {
|
:root {
|
||||||
--bg-color: #ffffff;
|
--bg-color: #ffffff;
|
||||||
--bg-secondary-color: #f3f3f6;
|
--bg-secondary-color: #f3f3f6;
|
||||||
|
--bg-tertiary-color: #cacad8;
|
||||||
--color-primary: #14854F;
|
--color-primary: #14854F;
|
||||||
--color-lightGrey: #d2d6dd;
|
--color-lightGrey: #d2d6dd;
|
||||||
|
--color-border: #d2d6dd;
|
||||||
--color-grey: #747681;
|
--color-grey: #747681;
|
||||||
--color-darkGrey: #3f4144;
|
--color-darkGrey: #3f4144;
|
||||||
--color-error: #d43939;
|
--color-error: #d43939;
|
||||||
|
|
@ -21,6 +23,39 @@
|
||||||
--font-color: #333333;
|
--font-color: #333333;
|
||||||
--font-family-sans: "Itim";
|
--font-family-sans: "Itim";
|
||||||
--font-family-mono: monaco, "Consolas", "Lucida Console", monospace;
|
--font-family-mono: monaco, "Consolas", "Lucida Console", monospace;
|
||||||
|
|
||||||
|
--msg-other-bg-color : rgb(75, 147, 196);
|
||||||
|
--msg-me-bg-color : rgb(101, 187, 130);
|
||||||
|
--msg-reply-bg-color : rgb(198, 203, 207);
|
||||||
|
--msg-other-border-color : #fff;
|
||||||
|
--msg-me-border-color : #fff;
|
||||||
|
--msg-reply-border-color : #fff;
|
||||||
|
--msg-other-border-sel-color : #fff;
|
||||||
|
--msg-me-border-sel-color : #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
scrollbar-width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark {
|
||||||
|
--bg-color: rgb(25, 25, 27);
|
||||||
|
--bg-secondary-color: #1f1f20;
|
||||||
|
--bg-tertiary-color: #28282b;
|
||||||
|
--font-color: #e5e7eb;
|
||||||
|
--color-grey: #ccc;
|
||||||
|
--color-lightGrey: #959ba5;
|
||||||
|
--color-darkGrey: rgb(140, 142, 146);
|
||||||
|
--color-border: rgb(140, 142, 146);
|
||||||
|
|
||||||
|
--msg-other-bg-color : #2C5AA0;
|
||||||
|
--msg-me-bg-color : #005544;
|
||||||
|
--msg-reply-bg-color : rgb(45, 46, 53);
|
||||||
|
--msg-other-border-color : #3771C8;
|
||||||
|
--msg-me-border-color : #008066;
|
||||||
|
--msg-reply-border-color : #717479;
|
||||||
|
--msg-other-border-sel-color : #ACDBFF;
|
||||||
|
--msg-me-border-sel-color : #8CE7A9;
|
||||||
}
|
}
|
||||||
|
|
||||||
body > .container {
|
body > .container {
|
||||||
|
|
@ -46,10 +81,30 @@ textarea {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
scrollbar-width: none;
|
||||||
|
background-color: var(--bg-secondary-color);
|
||||||
|
color: var(--font-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background-color: var(--bg-secondary-color);
|
||||||
|
color: var(--font-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-sec {
|
||||||
|
background-color: var(--bg-secondary-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-ter {
|
||||||
|
background-color: var(--bg-tertiary-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-white {
|
.bg-white {
|
||||||
background-color: white;
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background-color: var(--bg-tertiary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover-screen {
|
.cover-screen {
|
||||||
|
|
@ -137,6 +192,10 @@ textarea {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status .tag {
|
||||||
|
background-color: var(--bg-tertiary-color);
|
||||||
|
}
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
padding: 0px 8px 3px 8px;
|
padding: 0px 8px 3px 8px;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
|
|
@ -144,18 +203,18 @@ textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-other {
|
.message-other {
|
||||||
border-left: 5px solid #1E86D7;
|
border-left: 5px solid var(--msg-other-border-color);
|
||||||
background-color: #95C1E2;
|
background-color: var(--msg-other-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-me {
|
.message-me {
|
||||||
border-left: 5px solid #2F848D;
|
border-left: 5px solid var(--msg-me-border-color);
|
||||||
background-color: #99C5C9;
|
background-color: var(--msg-me-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-reply {
|
.message-reply {
|
||||||
border-left: 5px solid #383C4A;
|
border-left: 5px solid var(--msg-reply-border-color);
|
||||||
background-color: #DEDEDE;
|
background-color: var(--msg-reply-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.message .message-by {
|
.message .message-by {
|
||||||
|
|
@ -166,13 +225,13 @@ textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-me.active {
|
.message-me.active {
|
||||||
border: 2px dashed #11603F;
|
border: 3px dashed var(--msg-me-border-sel-color);
|
||||||
border-left: 5px solid #11603F;
|
border-left: 5px solid var(--msg-me-border-sel-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-other.active {
|
.message-other.active {
|
||||||
border: 2px dashed #104975;
|
border: 3px dashed var(--msg-other-border-sel-color);
|
||||||
border-left: 5px solid #104975;
|
border-left: 5px solid var(--msg-other-border-sel-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.clip-win {
|
.clip-win {
|
||||||
|
|
@ -182,6 +241,7 @@ textarea {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
bottom: 50px;
|
bottom: 50px;
|
||||||
border: 1px dashed #1E86D7;
|
border: 1px dashed #1E86D7;
|
||||||
|
background-color: var(--bg-secondary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.clip-win.reply-clip {
|
.clip-win.reply-clip {
|
||||||
|
|
@ -208,6 +268,17 @@ textarea {
|
||||||
max-width: 720px;
|
max-width: 720px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clip-win.action-clip button {
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clip-win.camera-clip {
|
||||||
|
width: 314px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
div[name="error_msg"] {
|
div[name="error_msg"] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<path style="fill:#D8D8DA;" d="M256,0C114.615,0,0,114.615,0,256s114.615,256,256,256s256-114.615,256-256S397.385,0,256,0z
|
||||||
|
M256,336.842c-44.648,0-80.842-36.194-80.842-80.842s36.194-80.842,80.842-80.842s80.842,36.194,80.842,80.842
|
||||||
|
S300.648,336.842,256,336.842z"/>
|
||||||
|
<path style="fill:#D4B6E6;" d="M282.947,188.632h220.076C485.09,122.726,441.507,67.394,383.64,34.044L229.053,188.632H282.947z"/>
|
||||||
|
<path style="fill:#EBAFD1;" d="M229.053,188.632L383.639,34.044C346.068,12.39,302.482,0,256,0c-23.319,0-45.899,3.135-67.368,8.978
|
||||||
|
v220.075L229.053,188.632z"/>
|
||||||
|
<path style="fill:#E07188;" d="M188.632,229.053V8.978C122.726,26.91,67.394,70.493,34.045,128.36l154.586,154.588V229.053z"/>
|
||||||
|
<g>
|
||||||
|
<polygon style="fill:#D8D8DA;" points="188.632,229.053 229.053,188.633 282.947,188.633 282.947,188.632 229.053,188.632 "/>
|
||||||
|
<polygon style="fill:#D8D8DA;" points="229.053,323.367 188.632,282.947 229.053,323.368 282.947,323.368 323.368,282.947
|
||||||
|
282.947,323.367 "/>
|
||||||
|
</g>
|
||||||
|
<path style="fill:#B4D8F1;" d="M503.024,188.632H282.947v0.001h0.958l39.463,40.42L477.955,383.64
|
||||||
|
C499.611,346.068,512,302.482,512,256C512,232.681,508.865,210.099,503.024,188.632z"/>
|
||||||
|
<path style="fill:#ACFFF4;" d="M323.368,282.947v220.075c65.905-17.932,121.238-61.517,154.586-119.382L323.368,229.053V282.947z"/>
|
||||||
|
<path style="fill:#95D5A7;" d="M282.947,323.368L128.361,477.956C165.932,499.61,209.518,512,256,512
|
||||||
|
c23.319,0,45.899-3.135,67.368-8.977V282.947L282.947,323.368z"/>
|
||||||
|
<path style="fill:#F8E99B;" d="M229.053,323.368H8.976C26.91,389.274,70.493,444.606,128.36,477.956l154.588-154.588H229.053z"/>
|
||||||
|
<path style="fill:#EFC27B;" d="M188.632,282.947L34.045,128.36C12.389,165.932,0,209.518,0,256c0,23.319,3.135,45.901,8.976,67.368
|
||||||
|
h220.076L188.632,282.947z"/>
|
||||||
|
<polygon style="fill:#D8D8DA;" points="283.905,188.633 282.947,188.633 323.368,229.053 "/>
|
||||||
|
<path style="fill:#B681D5;" d="M503.024,188.632C485.09,122.726,441.507,67.394,383.64,34.044L256,161.684v26.947h26.947H503.024z"
|
||||||
|
/>
|
||||||
|
<path style="fill:#E592BF;" d="M383.639,34.044C346.068,12.39,302.482,0,256,0v161.684L383.639,34.044z"/>
|
||||||
|
<path style="fill:#80CB93;" d="M256,350.316V512c23.319,0,45.899-3.135,67.368-8.977V282.947l-40.421,40.421L256,350.316z"/>
|
||||||
|
<polygon style="fill:#F6E27D;" points="282.947,323.368 256,323.368 256,350.316 "/>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -10,6 +10,5 @@
|
||||||
from="0 50 48"
|
from="0 50 48"
|
||||||
to="360 50 52"
|
to="360 50 52"
|
||||||
repeatCount="indefinite" />
|
repeatCount="indefinite" />
|
||||||
|
|
||||||
</circle>
|
</circle>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 584 B |
|
|
@ -28,28 +28,28 @@
|
||||||
guidetolerance="10"
|
guidetolerance="10"
|
||||||
inkscape:pageopacity="0"
|
inkscape:pageopacity="0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:window-width="1721"
|
inkscape:window-width="1920"
|
||||||
inkscape:window-height="1019"
|
inkscape:window-height="1021"
|
||||||
id="namedview39"
|
id="namedview39"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:zoom="0.20873984"
|
inkscape:zoom="0.41747968"
|
||||||
inkscape:cx="-1382.0481"
|
inkscape:cx="538.744"
|
||||||
inkscape:cy="-167.56932"
|
inkscape:cy="247.6787"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="0"
|
inkscape:window-y="0"
|
||||||
inkscape:window-maximized="0"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="Layer_1"
|
inkscape:current-layer="Layer_1"
|
||||||
inkscape:document-rotation="0" />
|
inkscape:document-rotation="0" />
|
||||||
<g
|
<g
|
||||||
id="g6"
|
id="g6"
|
||||||
style="fill:#f0efeb;fill-opacity:1">
|
style="fill:#938d71;fill-opacity:0.15649126">
|
||||||
<g
|
<g
|
||||||
id="g4"
|
id="g4"
|
||||||
style="fill:#f0efeb;fill-opacity:1">
|
style="fill:#938d71;fill-opacity:0.15649126">
|
||||||
<path
|
<path
|
||||||
d="m 503.032,394.775 h -76.738 l 82.927,-82.624 c 1.686,-1.681 2.636,-3.963 2.638,-6.346 0.002,-2.382 -0.941,-4.665 -2.625,-6.35 l -43.004,-43.03 43.01,-43.108 c 3.496,-3.504 3.492,-9.177 -0.008,-12.678 l -83.372,-83.362 77.179,-0.056 c 4.95,0 8.961,-4.016 8.961,-8.966 V 9.443 c 0,-4.955 -4.015,-8.969 -8.969,-8.969 h -98.812 c -4.955,0 -8.969,4.015 -8.969,8.969 V 86.676 L 311.664,3.1 c -1.681,-1.681 -3.963,-2.627 -6.344,-2.626 -2.379,0.001 -4.661,0.946 -6.343,2.63 L 255.976,46.141 212.935,3.1 c -1.683,-1.681 -3.963,-2.626 -6.343,-2.626 -2.38,0 -4.66,0.946 -6.343,2.627 L 116.752,86.633 V 9.443 c 0,-4.955 -4.016,-8.969 -8.969,-8.969 H 8.969 C 4.016,0.474 0,4.488 0,9.443 v 98.812 c 0,4.955 4.016,8.969 8.969,8.969 H 86.171 L 2.626,200.801 C 0.944,202.485 0,204.766 0,207.145 c 0,2.379 0.947,4.66 2.63,6.343 l 43.061,43.028 -43.065,43.098 c -1.684,1.685 -2.629,3.972 -2.625,6.354 0.004,2.382 0.954,4.665 2.643,6.347 l 82.891,82.462 H 8.969 C 4.016,394.777 0,398.792 0,403.746 v 98.812 c 0,4.955 4.016,8.969 8.969,8.969 h 98.812 c 4.953,0 8.969,-4.015 8.969,-8.969 v -76.726 l 83.517,83.085 c 1.75,1.74 4.037,2.611 6.326,2.611 2.294,0 4.589,-0.874 6.34,-2.624 l 43.085,-43.048 43.046,43.046 c 1.752,1.751 4.047,2.626 6.343,2.626 2.29,0 4.58,-0.872 6.331,-2.615 l 83.512,-83.207 v 76.852 c 0,4.955 4.015,8.969 8.969,8.969 h 98.812 c 4.955,0 8.969,-4.015 8.969,-8.969 v -98.812 c 10e-4,-4.956 -4.013,-8.971 -8.968,-8.971 z m -12.837,-88.991 -77.007,76.725 v -72.92 l 40.372,-40.464 z m 0.017,-98.791 -36.662,36.746 -40.361,-40.386 V 129.979 Z M 413.188,18.411 h 80.874 v 80.882 l -80.874,0.057 z m -107.862,3.718 77.221,77.213 -73.422,-0.053 -40.464,-40.465 z m 89.923,95.161 v 80.808 H 314.375 V 117.233 Z M 206.595,22.128 243.298,58.831 202.877,99.286 h -73.409 z m -89.844,95.096 h 80.874 v 80.874 H 116.751 Z M 17.939,99.286 V 18.412 h 80.874 v 80.874 z m 3.715,107.853 77.158,-77.187 v 73.401 L 58.37,243.827 Z m 77.158,286.45 H 17.939 v -80.874 h 80.874 v 80.874 z m 0,-110.908 -77.145,-76.745 36.712,-36.74 40.433,40.402 z m 107.769,107.211 -77.579,-77.177 h 73.876 l 40.455,40.455 z m -89.83,-95.115 V 314.85 l 80.869,-0.001 h 0.005 v 79.928 z m 188.667,95.108 -36.71,-36.71 40.413,-40.38 73.73,-0.062 z m 89.831,-95.1 -80.874,0.068 v -80.002 h 80.874 z m 5.249,-97.874 h -95.092 c -4.955,0 -8.969,4.015 -8.969,8.969 v 94.232 l -40.413,40.379 -40.461,-40.46 V 305.88 c 0,-2.379 -0.945,-4.659 -2.627,-6.343 -1.683,-1.681 -3.963,-2.626 -6.342,-2.626 l -95.099,10e-4 -40.435,-40.404 40.44,-40.471 h 95.095 c 4.953,0 8.969,-4.015 8.969,-8.969 v -95.1 l 40.418,-40.452 40.455,40.455 v 95.097 c 0,4.955 4.015,8.969 8.969,8.969 h 95.095 l 40.378,40.401 z m 93.563,196.678 h -80.874 v -80.874 h 80.874 z"
|
d="m 503.032,394.775 h -76.738 l 82.927,-82.624 c 1.686,-1.681 2.636,-3.963 2.638,-6.346 0.002,-2.382 -0.941,-4.665 -2.625,-6.35 l -43.004,-43.03 43.01,-43.108 c 3.496,-3.504 3.492,-9.177 -0.008,-12.678 l -83.372,-83.362 77.179,-0.056 c 4.95,0 8.961,-4.016 8.961,-8.966 V 9.443 c 0,-4.955 -4.015,-8.969 -8.969,-8.969 h -98.812 c -4.955,0 -8.969,4.015 -8.969,8.969 V 86.676 L 311.664,3.1 c -1.681,-1.681 -3.963,-2.627 -6.344,-2.626 -2.379,0.001 -4.661,0.946 -6.343,2.63 L 255.976,46.141 212.935,3.1 c -1.683,-1.681 -3.963,-2.626 -6.343,-2.626 -2.38,0 -4.66,0.946 -6.343,2.627 L 116.752,86.633 V 9.443 c 0,-4.955 -4.016,-8.969 -8.969,-8.969 H 8.969 C 4.016,0.474 0,4.488 0,9.443 v 98.812 c 0,4.955 4.016,8.969 8.969,8.969 H 86.171 L 2.626,200.801 C 0.944,202.485 0,204.766 0,207.145 c 0,2.379 0.947,4.66 2.63,6.343 l 43.061,43.028 -43.065,43.098 c -1.684,1.685 -2.629,3.972 -2.625,6.354 0.004,2.382 0.954,4.665 2.643,6.347 l 82.891,82.462 H 8.969 C 4.016,394.777 0,398.792 0,403.746 v 98.812 c 0,4.955 4.016,8.969 8.969,8.969 h 98.812 c 4.953,0 8.969,-4.015 8.969,-8.969 v -76.726 l 83.517,83.085 c 1.75,1.74 4.037,2.611 6.326,2.611 2.294,0 4.589,-0.874 6.34,-2.624 l 43.085,-43.048 43.046,43.046 c 1.752,1.751 4.047,2.626 6.343,2.626 2.29,0 4.58,-0.872 6.331,-2.615 l 83.512,-83.207 v 76.852 c 0,4.955 4.015,8.969 8.969,8.969 h 98.812 c 4.955,0 8.969,-4.015 8.969,-8.969 v -98.812 c 10e-4,-4.956 -4.013,-8.971 -8.968,-8.971 z m -12.837,-88.991 -77.007,76.725 v -72.92 l 40.372,-40.464 z m 0.017,-98.791 -36.662,36.746 -40.361,-40.386 V 129.979 Z M 413.188,18.411 h 80.874 v 80.882 l -80.874,0.057 z m -107.862,3.718 77.221,77.213 -73.422,-0.053 -40.464,-40.465 z m 89.923,95.161 v 80.808 H 314.375 V 117.233 Z M 206.595,22.128 243.298,58.831 202.877,99.286 h -73.409 z m -89.844,95.096 h 80.874 v 80.874 H 116.751 Z M 17.939,99.286 V 18.412 h 80.874 v 80.874 z m 3.715,107.853 77.158,-77.187 v 73.401 L 58.37,243.827 Z m 77.158,286.45 H 17.939 v -80.874 h 80.874 v 80.874 z m 0,-110.908 -77.145,-76.745 36.712,-36.74 40.433,40.402 z m 107.769,107.211 -77.579,-77.177 h 73.876 l 40.455,40.455 z m -89.83,-95.115 V 314.85 l 80.869,-0.001 h 0.005 v 79.928 z m 188.667,95.108 -36.71,-36.71 40.413,-40.38 73.73,-0.062 z m 89.831,-95.1 -80.874,0.068 v -80.002 h 80.874 z m 5.249,-97.874 h -95.092 c -4.955,0 -8.969,4.015 -8.969,8.969 v 94.232 l -40.413,40.379 -40.461,-40.46 V 305.88 c 0,-2.379 -0.945,-4.659 -2.627,-6.343 -1.683,-1.681 -3.963,-2.626 -6.342,-2.626 l -95.099,10e-4 -40.435,-40.404 40.44,-40.471 h 95.095 c 4.953,0 8.969,-4.015 8.969,-8.969 v -95.1 l 40.418,-40.452 40.455,40.455 v 95.097 c 0,4.955 4.015,8.969 8.969,8.969 h 95.095 l 40.378,40.401 z m 93.563,196.678 h -80.874 v -80.874 h 80.874 z"
|
||||||
id="path2"
|
id="path2"
|
||||||
style="fill:#f0efeb;fill-opacity:1" />
|
style="fill:#938d71;fill-opacity:0.15649126" />
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g
|
<g
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
|
@ -7,7 +7,7 @@
|
||||||
<title>Lupt Chat</title>
|
<title>Lupt Chat</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="progress" class="bg-white" style="z-index: 9999; position: fixed; top: 0; bottom: 0;width: 100%; height: 100%;">
|
<div id="progress" class="bg-sec" style="z-index: 9999; position: fixed; top: 0; bottom: 0;width: 100%; height: 100%;">
|
||||||
<div style="top: 50%;
|
<div style="top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
width:10em;
|
width:10em;
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
<div class="tabs is-center">
|
<div class="tabs is-center">
|
||||||
<a name="kaksh_sec" class="active">Kaksh(Room)</a>
|
<a name="kaksh_sec" class="active">Kaksh(Room)</a>
|
||||||
<a name="stranger_sec">Stranger</a>
|
<a name="stranger_sec">Stranger</a>
|
||||||
|
<a onclick="changeColor()"><img src="img/color.svg" alt="C" height="16"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form name="kaksh_sec" cmd="join">
|
<form name="kaksh_sec" cmd="join">
|
||||||
|
|
@ -108,7 +109,7 @@
|
||||||
|
|
||||||
<!-- Chat Screen -->
|
<!-- Chat Screen -->
|
||||||
<div id="chat_panel" class="cover-screen chatpanel is-hidden">
|
<div id="chat_panel" class="cover-screen chatpanel is-hidden">
|
||||||
<div class="chatpanel-top bg-light">
|
<div class="chatpanel-top bg-ter">
|
||||||
<button onclick="leave()" class="button chatpanel-top-l">
|
<button onclick="leave()" class="button chatpanel-top-l">
|
||||||
<img src="img/back.svg" alt="" height="12px"> Back
|
<img src="img/back.svg" alt="" height="12px"> Back
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -125,29 +126,30 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chatpanel-bot bg-light">
|
<div class="chatpanel-bot bg-ter">
|
||||||
<button onclick="$('#action_clip').toggleClass('is-hidden')" class="button chatpanel-bot-l">
|
<button onclick="$('#action_clip').toggleClass('is-hidden')" class="button chatpanel-bot-l">
|
||||||
<img src="img/clip.svg" alt="send" width="24">
|
<img src="img/clip.svg" alt="send" width="24">
|
||||||
</button>
|
</button>
|
||||||
<div class="chatpanel-bot-m">
|
<div class="chatpanel-bot-m">
|
||||||
<textarea id="send_box" rows="1"></textarea>
|
<textarea id="send_box" rows="1"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<button onclick="send()" class="button chatpanel-bot-r">
|
<button id="send_button" class="button chatpanel-bot-r">
|
||||||
<img src="img/send.svg" alt="Send" width="50">
|
<img src="img/send.svg" alt="Send" width="50">
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Reply Clip -->
|
<!-- Reply Clip -->
|
||||||
<div id="reply_clip" class="clip-win reply-clip bg-white is-hidden">
|
<div id="reply_clip" class="clip-win reply-clip is-hidden">
|
||||||
<span>sss</span>
|
<span></span>
|
||||||
<a onclick="$('#reply_clip > span').text(''); $('#reply_clip').addClass('is-hidden');" style="float: right; padding: 3px 6px;">
|
<a onclick="$('#reply_clip > span').text(''); $('#reply_clip').attr('msg', '');
|
||||||
|
$('#reply_clip').addClass('is-hidden');" style="float: right; padding: 3px 6px;">
|
||||||
<img src="img/close.svg" alt="X" style="height: 1.8rem; width: auto; cursor: pointer;">
|
<img src="img/close.svg" alt="X" style="height: 1.8rem; width: auto; cursor: pointer;">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Selected Clip -->
|
<!-- Selected Clip -->
|
||||||
<div id="selected_clip" class="clip-win selected-clip bg-white is-hidden">
|
<div id="selected_clip" class="clip-win selected-clip is-hidden">
|
||||||
<div style="padding: 4px;">
|
<div style="padding: 4px;">
|
||||||
<div onclick="Messages.copyMessagesToClipboard()" class="button outline primary">Copy</div>
|
<div onclick="Messages.copyMessagesToClipboard()" class="button outline primary">Copy</div>
|
||||||
<div onclick="Messages.prepareReply()" class="button outline primary">Reply</div>
|
<div onclick="Messages.prepareReply()" class="button outline primary">Reply</div>
|
||||||
|
|
@ -158,25 +160,33 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Action Clip -->
|
<!-- Action Clip -->
|
||||||
<div id="action_clip" class="clip-win action-clip is-hidden bg-white">
|
<div id="action_clip" class="clip-win action-clip is-hidden">
|
||||||
<div class="is-hidden">
|
<div style="padding-bottom: 10px;">
|
||||||
<button class="button">
|
<button class="button">
|
||||||
<img src="img/image.svg" alt="Image" width="50" class="siimple--py-2 siimple--px-2">
|
<img src="img/image.svg" alt="Image" width="50" class="siimple--py-2 siimple--px-2">
|
||||||
<div>send image</div>
|
<div>send image</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
<button onclick="changeColor()" class="button"><img src="img/color.svg" alt="C" height="16"></button>
|
||||||
<button onclick="Messages.cleanMessage()" class="button">Clear</button>
|
<button onclick="Messages.cleanMessage()" class="button">Clear</button>
|
||||||
<button onclick="vayaktiList()" class="button">List Vyakti(Users)</button>
|
<button onclick="vayaktiList()" class="button">List Vyakti(Users)</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Camera Clip -->
|
||||||
|
<div id="camera_clip" class="clip-win camera-clip is-hidden">
|
||||||
|
<video autoplay="true" id="videoElement" width="300"></video>
|
||||||
|
<button class="button is-full-width">Send</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- vayakti -->
|
<!-- vayakti -->
|
||||||
<div id="vayakti_model" class="card is-hidden" style="position: fixed; top: 50px; bottom: 50px; right: 0; z-index: 9999; width: 100%; max-width: 500px;">
|
<div id="vayakti_model" class="card is-hidden" style="position: fixed; top: 50px; bottom: 50px; right: 0; z-index: 9999; width: 100%; max-width: 500px;">
|
||||||
<header>
|
<header>
|
||||||
<h4>
|
<h4>
|
||||||
List Vyakti(Users)
|
List Vyakti(Users)
|
||||||
<button onclick="$('#vayakti_model').addClass('is-hidden'); $('#vayakti_list').empty()" class="button bg-red" style="float: right;"><img src="img/close.svg" alt="X" style="height: 1.8rem; width: auto; cursor: pointer;"></button>
|
<button onclick="$('#vayakti_model').addClass('is-hidden'); $('#vayakti_list').empty()" class="button bg-red pull-right"><img src="img/close.svg" alt="X" style="height: 1.8rem; width: auto; cursor: pointer;"></button>
|
||||||
</h4>
|
</h4>
|
||||||
</header>
|
</header>
|
||||||
<div style="overflow-y: scroll; height: calc(100% - 40px);">
|
<div style="overflow-y: scroll; height: calc(100% - 40px);">
|
||||||
|
|
@ -195,6 +205,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="js/jquery-3.5.1.min.js"></script>
|
<script src="js/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="js/actions.js"></script>
|
||||||
|
<script src="js/state.js"></script>
|
||||||
|
<script src="js/message.js"></script>
|
||||||
<script src="js/app.js"></script>
|
<script src="js/app.js"></script>
|
||||||
|
<script src="js/onload.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
class Actions {
|
||||||
|
actions = []; // [[id, func]]
|
||||||
|
|
||||||
|
execute() {
|
||||||
|
if(this.actions.length <= 0) return;
|
||||||
|
|
||||||
|
var act = this.actions[0];
|
||||||
|
this.actions.shift();
|
||||||
|
|
||||||
|
act[1]();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.actions = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_key(ac) {
|
||||||
|
this.actions = this.actions.filter(function (arr) {
|
||||||
|
return arr[0] != ac
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
has_key(ac) {
|
||||||
|
var out = this.actions.find(function (arr) {
|
||||||
|
return arr[0] == ac
|
||||||
|
});
|
||||||
|
return out != undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(id, func) {
|
||||||
|
this.actions.push([id, func]);
|
||||||
|
}
|
||||||
|
}
|
||||||
291
static/js/app.js
291
static/js/app.js
|
|
@ -1,253 +1,6 @@
|
||||||
|
|
||||||
let State = class {
|
|
||||||
static login() {
|
|
||||||
$('#connect_panel').removeClass('is-hidden');
|
|
||||||
$('#chat_panel').addClass('is-hidden');
|
|
||||||
$('#reply_clip').addClass('is-hidden');
|
|
||||||
$('#selected_clip').addClass('is-hidden');
|
|
||||||
$('#action_clip').addClass('is-hidden');
|
|
||||||
$('#vayakti_model').addClass('is-hidden');
|
|
||||||
$('[name="error_msg"]').addClass('is-hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
static chat() {
|
|
||||||
$('#chat_panel').removeClass('is-hidden');
|
|
||||||
$('#connect_panel').addClass('is-hidden');
|
|
||||||
$('#reply_clip').addClass('is-hidden');
|
|
||||||
$('#selected_clip').addClass('is-hidden');
|
|
||||||
$('#action_clip').addClass('is-hidden');
|
|
||||||
$('#vayakti_model').addClass('is-hidden');
|
|
||||||
$('#next_btn').addClass('is-hidden');
|
|
||||||
$('#send_box').focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
static showProgress() {
|
|
||||||
$('#progress').removeClass('is-hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
static hideProgress() {
|
|
||||||
$('#progress').addClass('is-hidden');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let Messages = class {
|
|
||||||
static pick(elm) {
|
|
||||||
var elm = $(elm);
|
|
||||||
elm.toggleClass('active');
|
|
||||||
|
|
||||||
if($('.active').length == 0)
|
|
||||||
$('#selected_clip').addClass('is-hidden');
|
|
||||||
else
|
|
||||||
$('#selected_clip').removeClass('is-hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
static unselectAll(msg) {
|
|
||||||
$('.active').each(function() {
|
|
||||||
$(this).removeClass('active');
|
|
||||||
});
|
|
||||||
$('#selected_clip').addClass('is-hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
static setupTyping() {
|
|
||||||
var send_typing = false;
|
|
||||||
var timeout = null;
|
|
||||||
$('#send_box').keydown(function(e) {
|
|
||||||
if (!send_typing) {
|
|
||||||
sendTyping();
|
|
||||||
send_typing = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(function() {
|
|
||||||
send_typing = false;
|
|
||||||
sendTypingEnd();
|
|
||||||
},2000);
|
|
||||||
});
|
|
||||||
$('#send_box').keypress(function(e) {
|
|
||||||
if(e.originalEvent.charCode == 13 && !e.shiftKey) {
|
|
||||||
send();
|
|
||||||
e.preventDefault();
|
|
||||||
clearTimeout(timeout);
|
|
||||||
send_typing = false;
|
|
||||||
sendTypingEnd()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static pushTypingStatus() {
|
|
||||||
var elm = $('#status_area > #typing');
|
|
||||||
if(elm.length > 0) elm.remove();
|
|
||||||
if(typing.length == 0) return;
|
|
||||||
var text = '';
|
|
||||||
typing.forEach((val) => {
|
|
||||||
var name = vayakti[val];
|
|
||||||
if(name == undefined) name = "";
|
|
||||||
text += name+'('+val.substr(0,8)+')'+ ','
|
|
||||||
})
|
|
||||||
text = text.substr(0, text.length-1);
|
|
||||||
text += ' is typing...'
|
|
||||||
$('#status_area').append($('<div>', { id: 'typing' }).append(text));
|
|
||||||
|
|
||||||
var scroll = $("#message_area_scroll");
|
|
||||||
scroll.scrollTop(scroll[0].scrollHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
static pushMessage(sender, text, reply = null) {
|
|
||||||
var isMe = myinfo.kunjika == sender;
|
|
||||||
var area = $('#message_area');
|
|
||||||
var elm = $('<div>', {class: 'message '+(isMe?'message-me':'message-other')});
|
|
||||||
if(!no_name_message) {
|
|
||||||
if(sender == myinfo.kunjika)
|
|
||||||
elm.append($('<div>', {class: 'message-by'}).append('me'))
|
|
||||||
else
|
|
||||||
elm.append($('<div>', {class: 'message-by'}).append(vayakti[sender]+'('+sender.substr(0, 8)+')'))
|
|
||||||
}
|
|
||||||
if(reply != null && reply.length > 0) {
|
|
||||||
elm.append(
|
|
||||||
$('<div>', {class: 'message message-reply'})
|
|
||||||
.append($('<pre>').append(reply))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
elm.append($('<pre>').append(text));
|
|
||||||
elm.click(function() {
|
|
||||||
Messages.pick(this);
|
|
||||||
});
|
|
||||||
area.append(elm);
|
|
||||||
|
|
||||||
var scroll = $("#message_area_scroll");
|
|
||||||
scroll.scrollTop(scroll[0].scrollHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
// in message area
|
|
||||||
static pushStatus(text) {
|
|
||||||
var area = $('#message_area');
|
|
||||||
var elm = $('<div>', {class: 'status'});
|
|
||||||
elm.append($('<small>', {class: 'tag bg-light'}).append(text));
|
|
||||||
area.append(elm);
|
|
||||||
|
|
||||||
var scroll = $("#message_area_scroll");
|
|
||||||
scroll.scrollTop(scroll[0].scrollHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
static selectedMessageToText() {
|
|
||||||
var text = "";
|
|
||||||
$('.active').each(function() {
|
|
||||||
$(this).find('pre').each(function() {
|
|
||||||
text += $(this).text() + '\n'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return text.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
static prepareReply() {
|
|
||||||
var text = this.selectedMessageToText();
|
|
||||||
var el = $('#reply_clip');
|
|
||||||
el.removeClass('is-hidden');
|
|
||||||
el.attr('msg', text);
|
|
||||||
$('#reply_clip > span').text(text.substr(0, 15)+ '...');
|
|
||||||
Messages.unselectAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
static copyMessagesToClipboard() {
|
|
||||||
var $temp = $("<textarea>");
|
|
||||||
$("body").append($temp);
|
|
||||||
$temp.val(this.selectedMessageToText()).select();
|
|
||||||
document.execCommand("copy");
|
|
||||||
$temp.remove();
|
|
||||||
Messages.unselectAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
static cleanMessage() {
|
|
||||||
$('#message_area').empty();
|
|
||||||
$('#status_area').empty();
|
|
||||||
$('#action_clip').addClass('is-hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
static currentTime() {
|
|
||||||
var today = new Date();
|
|
||||||
return today.getHours()+':'+today.getMinutes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Actions {
|
|
||||||
actions = []; // [[id, func]]
|
|
||||||
|
|
||||||
execute() {
|
|
||||||
if(this.actions.length <= 0) return;
|
|
||||||
|
|
||||||
var act = this.actions[0];
|
|
||||||
this.actions.shift();
|
|
||||||
|
|
||||||
act[1]();
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.actions = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_key(ac) {
|
|
||||||
this.actions = this.actions.filter(function (arr) {
|
|
||||||
return arr[0] != ac
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
has_key(ac) {
|
|
||||||
var out = this.actions.find(function (arr) {
|
|
||||||
return arr[0] == ac
|
|
||||||
});
|
|
||||||
return out != undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
add(id, func) {
|
|
||||||
this.actions.push([id, func]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var actions = new Actions();
|
var actions = new Actions();
|
||||||
|
|
||||||
$(document).ready(() => {
|
|
||||||
$(".tabs > a").click(function() {
|
|
||||||
var t = $(this);
|
|
||||||
$(t.parents('tabs').first()).find('form').each(function(i,elm) {
|
|
||||||
var elm = $(elm);
|
|
||||||
if(elm.attr('name') == t.attr('name'))
|
|
||||||
elm.removeClass('is-hidden');
|
|
||||||
else elm.addClass('is-hidden');
|
|
||||||
});
|
|
||||||
$(".tabs > a").each(function(i,elm) {
|
|
||||||
var elm = $(elm);
|
|
||||||
if(elm.attr('name') != t.attr('name'))
|
|
||||||
elm.removeClass('active');
|
|
||||||
else elm.addClass('active');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.message-me, .message-other').click(function() {
|
|
||||||
Messages.select();
|
|
||||||
});
|
|
||||||
|
|
||||||
Messages.setupTyping();
|
|
||||||
|
|
||||||
$('[name=connect]').click(function () {
|
|
||||||
State.showProgress();
|
|
||||||
connect($(this).parents('form').first());
|
|
||||||
});
|
|
||||||
|
|
||||||
var textarea = $('#send_box')[0];
|
|
||||||
|
|
||||||
textarea.addEventListener('keydown', autosize);
|
|
||||||
|
|
||||||
function autosize(){
|
|
||||||
var el = this;
|
|
||||||
setTimeout(function(){
|
|
||||||
el.style.cssText = 'height:auto; padding:0';
|
|
||||||
el.style.cssText = 'height:' + el.scrollHeight + 'px';
|
|
||||||
},0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create WebSocket connection.
|
// Create WebSocket connection.
|
||||||
var wsProtocol = 'ws://';
|
var wsProtocol = 'ws://';
|
||||||
if (window.location.protocol === 'https:') {
|
if (window.location.protocol === 'https:') {
|
||||||
|
|
@ -321,7 +74,7 @@ socket.addEventListener('message', function (event) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'text':
|
case 'text':
|
||||||
Messages.pushMessage(j.kunjika, j.text, j.reply);
|
Messages.pushMessage(j.kunjika, j.text, j.reply, j.msg_id);
|
||||||
break;
|
break;
|
||||||
case 'connected':
|
case 'connected':
|
||||||
vayakti[j.kunjika] = j.name;
|
vayakti[j.kunjika] = j.name;
|
||||||
|
|
@ -431,6 +184,7 @@ function send() {
|
||||||
$('#reply_clip').attr('msg', '');
|
$('#reply_clip').attr('msg', '');
|
||||||
$('#reply_clip').addClass('is-hidden');
|
$('#reply_clip').addClass('is-hidden');
|
||||||
$('#reply_clip > span').text('');
|
$('#reply_clip > span').text('');
|
||||||
|
autosize($('#send_box')[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function vayaktiList() {
|
function vayaktiList() {
|
||||||
|
|
@ -439,6 +193,11 @@ function vayaktiList() {
|
||||||
$('#action_clip').addClass('is-hidden');
|
$('#action_clip').addClass('is-hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeColor() {
|
||||||
|
$('body').toggleClass('dark')
|
||||||
|
$('#action_clip').addClass('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
function refreshVayaktiList() {
|
function refreshVayaktiList() {
|
||||||
var v = $('#vayakti_list');
|
var v = $('#vayakti_list');
|
||||||
v.empty();
|
v.empty();
|
||||||
|
|
@ -448,3 +207,39 @@ function refreshVayaktiList() {
|
||||||
.append($('<td>').append(key)));
|
.append($('<td>').append(key)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function autosize(el){
|
||||||
|
setTimeout(function(){
|
||||||
|
el.style.cssText = 'height:auto; padding:0';
|
||||||
|
el.style.cssText = 'height:' + el.scrollHeight + 'px';
|
||||||
|
$('#reply_clip').css('bottom', (el.scrollHeight + 10) + 'px');
|
||||||
|
$('#selected_clip').css('bottom', (el.scrollHeight + 10) + 'px');
|
||||||
|
},0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Camera
|
||||||
|
var video = $('#videoElement')[0];
|
||||||
|
if (navigator.mediaDevices.getUserMedia) {
|
||||||
|
navigator.mediaDevices.getUserMedia({ video: true, width: {max: 100} })
|
||||||
|
.then(function (stream) {
|
||||||
|
video.srcObject = stream;
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log('Something went wrong!');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultb64='';
|
||||||
|
function capture() {
|
||||||
|
var canvas = $('<canvas>')[0];
|
||||||
|
var video = $('#videoElement')[0];
|
||||||
|
canvas.width = 200;
|
||||||
|
canvas.height = 200;
|
||||||
|
canvas.getContext('2d').drawImage(video, 0, 0, 120,120);
|
||||||
|
resultb64=canvas.toDataURL();
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
cmd: 'text',
|
||||||
|
text: resultb64,
|
||||||
|
reply: ''
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
|
||||||
|
let Messages = class {
|
||||||
|
static pick(elm) {
|
||||||
|
var elm = $(elm);
|
||||||
|
elm.toggleClass('active');
|
||||||
|
|
||||||
|
if($('.active').length == 0)
|
||||||
|
$('#selected_clip').addClass('is-hidden');
|
||||||
|
else
|
||||||
|
$('#selected_clip').removeClass('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
static unselectAll(msg) {
|
||||||
|
$('.active').each(function() {
|
||||||
|
$(this).removeClass('active');
|
||||||
|
});
|
||||||
|
$('#selected_clip').addClass('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
static setupTyping() {
|
||||||
|
var send_typing = false;
|
||||||
|
var timeout = null;
|
||||||
|
$('#send_box').keydown(function(e) {
|
||||||
|
if (!send_typing) {
|
||||||
|
sendTyping();
|
||||||
|
send_typing = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(function() {
|
||||||
|
send_typing = false;
|
||||||
|
sendTypingEnd();
|
||||||
|
},2000);
|
||||||
|
});
|
||||||
|
$('#send_box').keypress(function(e) {
|
||||||
|
if(e.originalEvent.charCode == 13 && !e.shiftKey) {
|
||||||
|
send();
|
||||||
|
e.preventDefault();
|
||||||
|
clearTimeout(timeout);
|
||||||
|
send_typing = false;
|
||||||
|
sendTypingEnd()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static pushTypingStatus() {
|
||||||
|
var elm = $('#status_area > #typing');
|
||||||
|
if(elm.length > 0) elm.remove();
|
||||||
|
if(typing.length == 0) return;
|
||||||
|
var text = '';
|
||||||
|
typing.forEach((val) => {
|
||||||
|
var name = vayakti[val];
|
||||||
|
if(name == undefined) name = "";
|
||||||
|
text += name+'('+val.substr(0,8)+')'+ ','
|
||||||
|
})
|
||||||
|
text = text.substr(0, text.length-1);
|
||||||
|
text += ' is typing...'
|
||||||
|
$('#status_area').append($('<div>', { id: 'typing' }).append(text));
|
||||||
|
|
||||||
|
var scroll = $("#message_area_scroll");
|
||||||
|
scroll.scrollTop(scroll[0].scrollHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pushMessage(sender, text, reply = null, msg_id) {
|
||||||
|
var isMe = myinfo.kunjika == sender;
|
||||||
|
var area = $('#message_area');
|
||||||
|
var elm = $('<div>', {class: 'message '+(isMe?'message-me':'message-other'), msgid: msg_id});
|
||||||
|
if(!no_name_message) {
|
||||||
|
if(sender == myinfo.kunjika)
|
||||||
|
elm.append($('<div>', {class: 'message-by'}).append('me'))
|
||||||
|
else
|
||||||
|
elm.append($('<div>', {class: 'message-by'}).append(vayakti[sender]+'('+sender.substr(0, 8)+')'))
|
||||||
|
}
|
||||||
|
if(reply != null && reply.length > 0) {
|
||||||
|
elm.append(
|
||||||
|
$('<div>', {class: 'message message-reply'})
|
||||||
|
.append($('<pre>').append(reply))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elm.append($('<pre>').append(text));
|
||||||
|
elm.click(function() {
|
||||||
|
Messages.pick(this);
|
||||||
|
});
|
||||||
|
area.append(elm);
|
||||||
|
|
||||||
|
var scroll = $("#message_area_scroll");
|
||||||
|
scroll.scrollTop(scroll[0].scrollHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// in message area
|
||||||
|
static pushStatus(text) {
|
||||||
|
var area = $('#message_area');
|
||||||
|
var elm = $('<div>', {class: 'status'});
|
||||||
|
elm.append($('<small>', {class: 'tag'}).append(text));
|
||||||
|
area.append(elm);
|
||||||
|
|
||||||
|
var scroll = $("#message_area_scroll");
|
||||||
|
scroll.scrollTop(scroll[0].scrollHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
static selectedMessageToText() {
|
||||||
|
var text = "";
|
||||||
|
$('.active').each(function() {
|
||||||
|
$(this).find('pre').each(function() {
|
||||||
|
text += $(this).text() + '\n'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return text.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
static prepareReply() {
|
||||||
|
var text = this.selectedMessageToText();
|
||||||
|
var el = $('#reply_clip');
|
||||||
|
el.removeClass('is-hidden');
|
||||||
|
el.attr('msg', text);
|
||||||
|
$('#reply_clip > span').text(text.substr(0, 15)+ '...');
|
||||||
|
Messages.unselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
static copyMessagesToClipboard() {
|
||||||
|
var $temp = $("<textarea>");
|
||||||
|
$("body").append($temp);
|
||||||
|
$temp.val(this.selectedMessageToText()).select();
|
||||||
|
document.execCommand("copy");
|
||||||
|
$temp.remove();
|
||||||
|
Messages.unselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cleanMessage() {
|
||||||
|
$('#message_area').empty();
|
||||||
|
$('#status_area').empty();
|
||||||
|
$('#action_clip').addClass('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
static currentTime() {
|
||||||
|
var today = new Date();
|
||||||
|
return today.getHours()+':'+('0' + today.getMinutes()).slice(-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
$('body').toggleClass('dark');
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(() => {
|
||||||
|
|
||||||
|
$(".tabs > a").click(function() {
|
||||||
|
var t = $(this);
|
||||||
|
if(!this.hasAttribute('name')) return;
|
||||||
|
$(t.parents('tabs').first()).find('form').each(function(i,elm) {
|
||||||
|
var elm = $(elm);
|
||||||
|
if(elm.attr('name') == t.attr('name'))
|
||||||
|
elm.removeClass('is-hidden');
|
||||||
|
else elm.addClass('is-hidden');
|
||||||
|
});
|
||||||
|
$(".tabs > a").each(function(i,elm) {
|
||||||
|
var elm = $(elm);
|
||||||
|
if(elm.attr('name') != t.attr('name'))
|
||||||
|
elm.removeClass('active');
|
||||||
|
else elm.addClass('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.message-me, .message-other').click(function() {
|
||||||
|
Messages.select();
|
||||||
|
});
|
||||||
|
|
||||||
|
Messages.setupTyping();
|
||||||
|
|
||||||
|
$('[name=connect]').click(function () {
|
||||||
|
State.showProgress();
|
||||||
|
connect($(this).parents('form').first());
|
||||||
|
});
|
||||||
|
|
||||||
|
var textarea = $('#send_box')[0];
|
||||||
|
|
||||||
|
textarea.addEventListener('keydown', function() {
|
||||||
|
autosize(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
autosize($('#send_box')[0]);
|
||||||
|
|
||||||
|
$('#send_button').mousedown(function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
send();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
let State = class {
|
||||||
|
static login() {
|
||||||
|
$('#connect_panel').removeClass('is-hidden');
|
||||||
|
$('#chat_panel').addClass('is-hidden');
|
||||||
|
$('#reply_clip').addClass('is-hidden');
|
||||||
|
$('#selected_clip').addClass('is-hidden');
|
||||||
|
$('#action_clip').addClass('is-hidden');
|
||||||
|
$('#vayakti_model').addClass('is-hidden');
|
||||||
|
$('[name="error_msg"]').addClass('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
static chat() {
|
||||||
|
$('#chat_panel').removeClass('is-hidden');
|
||||||
|
$('#connect_panel').addClass('is-hidden');
|
||||||
|
$('#reply_clip').addClass('is-hidden');
|
||||||
|
$('#selected_clip').addClass('is-hidden');
|
||||||
|
$('#action_clip').addClass('is-hidden');
|
||||||
|
$('#vayakti_model').addClass('is-hidden');
|
||||||
|
$('#next_btn').addClass('is-hidden');
|
||||||
|
$('#send_box').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
static showProgress() {
|
||||||
|
$('#progress').removeClass('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
static hideProgress() {
|
||||||
|
$('#progress').addClass('is-hidden');
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue