emoji and bug fixes

This commit is contained in:
Piyush मिश्रः 2021-05-11 20:54:24 +05:30
parent 4b579e84bb
commit 99a2d73c6a
15 changed files with 481 additions and 40 deletions

View File

@ -51,6 +51,15 @@ pub struct SendImage {
pub kunjika: String,
pub src: String
}
/// Request to reaction
#[derive(Clone, Message)]
#[rtype(result = "()")]
pub struct SendReaction {
pub kaksh_kunjika: String,
pub kunjika: String,
pub emoji: String,
pub msg_id: String
}
// Request to send status
#[derive(Clone, Message)]

View File

@ -27,6 +27,15 @@ pub struct WsImage {
pub sender_kunjika: String,
pub msg_id: u128
}
// Request to send REaction
#[derive(Clone, Message)]
#[rtype(result = "()")]
pub struct WsReaction {
pub emoji: String,
pub sender_kunjika: String,
pub msg_id: String
}
// Request to send transfer status
#[derive(Clone, Message)]

View File

@ -40,6 +40,23 @@ impl Handler<ms::pind::SendImage> for ChatPinnd {
}
}
/// send Reaction to everyone
impl Handler<ms::pind::SendReaction> for ChatPinnd {
type Result = ();
fn handle(&mut self, msg: ms::pind::SendReaction, _: &mut Self::Context) -> Self::Result {
if let Some(kaksh) = self.kaksh.get_mut(&msg.kaksh_kunjika) {
kaksh.loog.iter().for_each(|c| {
c.addr.do_send(ms::sansad::WsReaction {
sender_kunjika: msg.kunjika.to_owned(),
emoji: msg.emoji.to_owned(),
msg_id: msg.msg_id.to_owned()
});
});
}
}
}
/// send status to everyone
impl Handler<ms::pind::SendStatus> for ChatPinnd {
type Result = ();

View File

@ -48,6 +48,7 @@ impl Actor for ChatPinnd {
// for actix broker
self.subscribe_system_async::<ms::pind::SendText>(ctx);
self.subscribe_system_async::<ms::pind::SendImage>(ctx);
self.subscribe_system_async::<ms::pind::SendReaction>(ctx);
self.subscribe_system_async::<ms::pind::DeleteMsg>(ctx);
self.subscribe_system_async::<ms::pind::EditMsg>(ctx);
self.subscribe_system_async::<ms::pind::SendStatus>(ctx);

View File

@ -30,6 +30,20 @@ impl Handler<ms::sansad::WsImage> for WsSansad {
}
}
/// send image message
impl Handler<ms::sansad::WsReaction> for WsSansad {
type Result = ();
fn handle(&mut self, msg: ms::sansad::WsReaction, ctx: &mut Self::Context) -> Self::Result {
let json = json!({
"cmd": "react",
"emoji": msg.emoji,
"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 = ();

View File

@ -127,6 +127,56 @@ impl WsSansad {
});
}
/// send reaction to vayakti in kaksh
pub async fn send_reaction(&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 emoji
let emoji = match val.get("emoji") {
Some(val) => val,
None => {
self.send_err_response("Invalid request");
return;
}
}.as_str().unwrap().to_owned();
// sent emoji
let msg_id = match val.get("msg_id") {
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::SendReaction {
kaksh_kunjika,
kunjika: self.kunjika.to_owned(),
emoji,
msg_id
});
}
/// delete text to vayakti in kaksh
pub async fn delete_msg(&mut self, val: Value) {
// check if vayakti exist

View File

@ -107,6 +107,7 @@ impl WsSansad {
"randnext" => { self.join_random_next().await },
"text" => { self.send_text(val).await },
"img" => { self.send_image(val).await },
"react" => { self.send_reaction(val).await },
"status" => { self.send_status(val).await },
"del" => { self.delete_msg(val).await },
"edit" => { self.edit_msg(val).await },

38
static/img/heart.svg Normal file
View File

@ -0,0 +1,38 @@
<?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="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<path style="fill:#D75A4A;" d="M24.85,10.126c2.018-4.783,6.628-8.125,11.99-8.125c7.223,0,12.425,6.179,13.079,13.543
c0,0,0.353,1.828-0.424,5.119c-1.058,4.482-3.545,8.464-6.898,11.503L24.85,48L7.402,32.165c-3.353-3.038-5.84-7.021-6.898-11.503
c-0.777-3.291-0.424-5.119-0.424-5.119C0.734,8.179,5.936,2,13.159,2C18.522,2,22.832,5.343,24.85,10.126z"/>
<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: 879 B

66
static/img/laugh.svg Normal file
View File

@ -0,0 +1,66 @@
<?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">
<circle style="fill:#F7B239;" cx="255.995" cy="256" r="225.632"/>
<path style="fill:#E09B2D;" d="M137.457,374.547C56.289,293.38,49.893,165.759,118.263,77.268
c-7.573,5.851-14.86,12.247-21.807,19.193c-88.113,88.113-88.113,230.973,0,319.086s230.973,88.113,319.086,0
c6.946-6.946,13.342-14.234,19.194-21.807C346.244,462.11,218.624,455.714,137.457,374.547z"/>
<g>
<path style="fill:#4D4D4D;" d="M187.314,198.885c-4.619,0-8.363-3.744-8.363-8.363c0-19.986-16.26-36.246-36.246-36.246
s-36.246,16.26-36.246,36.246c0,4.619-3.744,8.363-8.363,8.363c-4.619,0-8.363-3.744-8.363-8.363
c0-29.209,23.763-52.972,52.972-52.972s52.972,23.763,52.972,52.972C195.677,195.141,191.933,198.885,187.314,198.885z"/>
<path style="fill:#4D4D4D;" d="M413.903,198.885c-4.62,0-8.363-3.744-8.363-8.363c0-19.986-16.26-36.246-36.246-36.246
c-19.985,0-36.245,16.26-36.245,36.246c0,4.619-3.743,8.363-8.363,8.363s-8.363-3.744-8.363-8.363
c0-29.209,23.763-52.972,52.971-52.972s52.972,23.763,52.972,52.972C422.266,195.141,418.522,198.885,413.903,198.885z"/>
</g>
<path style="fill:#2BA5F7;" d="M0,256.004L0,256.004c0-27.089,21.96-49.048,49.048-49.048h49.048v49.048
c0,27.088-21.96,49.048-49.048,49.048l0,0C21.96,305.053,0,283.093,0,256.004z"/>
<path style="fill:#2197D8;" d="M23.251,256.004L23.251,256.004c0-27.089,21.96-49.048,49.048-49.048H49.048
C21.96,206.956,0,228.916,0,256.004l0,0c0,27.089,21.96,49.048,49.048,49.048l0,0c4.008,0,7.898-0.492,11.626-1.398
C39.199,298.433,23.251,279.086,23.251,256.004z"/>
<path style="fill:#2BA5F7;" d="M512,256.004L512,256.004c0-27.089-21.96-49.048-49.048-49.048h-49.048v49.048
c0,27.088,21.96,49.048,49.048,49.048l0,0C490.04,305.053,512,283.093,512,256.004z"/>
<path style="fill:#2197D8;" d="M432.397,256.004v-49.048h-18.494v49.048c0,27.089,21.96,49.048,49.048,49.048l0,0
c3.162,0,6.251-0.311,9.247-0.883C449.533,299.844,432.397,279.931,432.397,256.004z"/>
<path style="fill:#A81004;" d="M165.006,232.899c-6.669-5.017-16.205-0.206-16.205,8.139v16.861v12.756
c0,33.608,15.466,63.614,39.685,83.25c18.432,14.975,41.926,23.94,67.517,23.94s49.085-8.965,67.517-23.94
c2.888-2.342,5.653-4.828,8.274-7.46c19.402-19.391,31.4-46.186,31.4-75.79v-12.756V241.04c0-8.346-9.536-13.157-16.205-8.139
C293.249,273.331,218.752,273.331,165.006,232.899z"/>
<path style="fill:#F2F2F2;" d="M363.194,241.04v16.859c-59.198,59.198-155.183,59.198-214.392,0v-16.861
c0-8.345,9.536-13.157,16.205-8.139c53.746,40.432,128.243,40.433,181.982,0.002C353.657,227.883,363.194,232.694,363.194,241.04z"
/>
<path style="fill:#F95428;" d="M283.41,330.049c17.395,0.096,32.46,9.892,40.11,24.229c-18.514,14.874-42.058,23.708-67.648,23.567
s-49.035-9.236-67.384-24.313c7.795-14.253,22.98-23.881,40.363-23.784c10.225,0.057,19.651,3.464,27.235,9.182
C263.733,333.297,273.185,329.993,283.41,330.049z"/>
<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: 3.3 KiB

47
static/img/like.svg Normal file
View File

@ -0,0 +1,47 @@
<?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="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 56 56" style="enable-background:new 0 0 56 56;" xml:space="preserve">
<rect x="1.5" y="20" style="fill:#4B6DAA;" width="14" height="36"/>
<circle style="fill:#D8A852;" cx="8.5" cy="47" r="4"/>
<path style="fill:#FBCE9D;" d="M53.5,26c0-2.209-1.791-4-4-4h-9h-3h-3.602l0.988-4.619c0.754-3.524,0.552-7.819,0.104-10.836
C34.542,3.528,31.84,0,29.013,0h-0.239C26.364,0,25.5,2.659,25.5,6c0,16.25-8,16-8,16h-2v32h15h10h4c2.209,0,4-1.791,4-4
c0-2.209-1.791-4-4-4h3c2.209,0,4-1.791,4-4c0-2.209-1.791-4-4-4h3c2.209,0,4-1.791,4-4c0-2.493-1.613-3.442-4-3.796
C49.337,30.031,47.224,30,46.5,30h3C51.709,30,53.5,28.209,53.5,26z"/>
<path style="fill:#F7B563;" d="M52.12,29H39.5c-0.552,0-1,0.447-1,1s0.448,1,1,1h13.456c-0.657-0.403-1.488-0.653-2.456-0.796
C49.337,30.031,47.224,30,46.5,30h3C50.508,30,51.417,29.615,52.12,29z"/>
<path style="fill:#F7B563;" d="M53.12,37H39.5c-0.552,0-1,0.447-1,1s0.448,1,1,1h10.621c-0.703-0.615-1.613-1-2.621-1h3
C51.508,38,52.417,37.615,53.12,37z"/>
<path style="fill:#F7B563;" d="M50.12,45H37.5c-0.552,0-1,0.447-1,1s0.448,1,1,1h9.621c-0.703-0.615-1.613-1-2.621-1h3
C48.508,46,49.417,45.615,50.12,45z"/>
<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: 1.6 KiB

61
static/img/sad.svg Normal file
View File

@ -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.009 512.009" style="enable-background:new 0 0 512.009 512.009;" xml:space="preserve">
<circle style="fill:#F7B239;" cx="256.004" cy="256.004" r="256.004"/>
<g>
<path style="fill:#E09B2D;" d="M121.499,390.501C29.407,298.407,22.15,153.608,99.723,53.204
c-8.593,6.638-16.861,13.895-24.743,21.777c-99.974,99.974-99.974,262.065,0,362.038s262.065,99.974,362.038,0
c7.881-7.881,15.138-16.15,21.777-24.743C358.392,489.85,213.593,482.593,121.499,390.501z"/>
<path style="fill:#E09B2D;" d="M288.234,367.985c-1.484,0-2.988-0.349-4.394-1.084c-8.513-4.457-18.142-6.814-27.845-6.814
c-9.699,0-19.324,2.356-27.836,6.813c-4.639,2.432-10.376,0.639-12.808-4.004c-2.43-4.642-0.638-10.377,4.004-12.807
c11.218-5.874,23.887-8.979,36.64-8.979c12.755,0,25.428,3.105,36.647,8.979c4.643,2.43,6.436,8.165,4.005,12.807
C294.954,366.133,291.651,367.985,288.234,367.985z"/>
</g>
<g>
<path style="fill:#4D4D4D;" d="M257.185,302.041c-39.121,0-75.902,15.235-103.564,42.898c-3.706,3.706-3.706,9.713,0,13.418
c3.707,3.706,9.714,3.706,13.42,0c24.077-24.078,56.092-37.34,90.145-37.34s66.068,13.261,90.145,37.34
c1.853,1.853,4.281,2.78,6.71,2.78c2.428,0,4.857-0.926,6.71-2.78c3.706-3.706,3.706-9.713,0-13.418
C333.087,317.276,296.306,302.041,257.185,302.041z"/>
<path style="fill:#4D4D4D;" d="M158.362,132.143c0-5.24-4.247-9.489-9.489-9.489c-5.242,0-9.489,4.248-9.489,9.489
c0,27.852-22.659,50.513-50.513,50.513c-5.242,0-9.489,4.248-9.489,9.489c0,5.24,4.247,9.489,9.489,9.489
C127.189,201.632,158.362,170.46,158.362,132.143z"/>
<path style="fill:#4D4D4D;" d="M423.128,182.654c-27.854,0-50.513-22.659-50.513-50.513c0-5.24-4.247-9.489-9.489-9.489
s-9.489,4.248-9.489,9.489c0,38.317,31.173,69.49,69.49,69.49c5.242,0,9.489-4.248,9.489-9.489
C432.617,186.903,428.369,182.654,423.128,182.654z"/>
<path style="fill:#4D4D4D;" d="M177.781,229.019c0-19.358-15.749-35.107-35.107-35.107s-35.107,15.749-35.107,35.107
s15.749,35.107,35.107,35.107S177.781,248.377,177.781,229.019z"/>
<path style="fill:#4D4D4D;" d="M369.326,193.912c-19.358,0-35.107,15.749-35.107,35.107s15.749,35.107,35.107,35.107
s35.107-15.749,35.107-35.107S388.684,193.912,369.326,193.912z"/>
</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>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -143,6 +143,8 @@
</div>
</div>
<!-- Reply Clip -->
<div id="reply_clip" class="clip-win reply-clip is-hidden">
<img id="replyicon" src="img/edit.svg" class="svg-filter is-hidden" style="height: 1.6rem;">
@ -243,6 +245,7 @@
}
</script>
<script src="js/jquery-3.5.1.min.js"></script>
<script src="js/taphold.js"></script>
<script src="js/compressor.min.js"></script>
<script src="js/actions.js"></script>
<script src="js/state.js"></script>

View File

@ -47,7 +47,7 @@ socket.onerror = function(event) {
// Listen for messages
socket.onmessage = function(event) {
var j = JSON.parse(event.data);
// console.log(j);
console.log(j);
switch(j.cmd) {
case 'resp':
if(j.result == 'Err') {
@ -84,11 +84,14 @@ socket.onmessage = function(event) {
}
break;
case 'text':
Messages.pushMessage(j.kunjika, j.text, j.reply, j.msg_id);
Messages.pushText(j.kunjika, j.text, j.reply, j.msg_id);
break;
case 'img':
Messages.pushImage(j.kunjika, j.src, j.msg_id);
break;
case 'react':
Messages.addReaction(j.kunjika, j.emoji, j.msg_id);
break;
case 'del':
Messages.deleteMessages(j.msg_id);
break;
@ -102,6 +105,11 @@ socket.onmessage = function(event) {
break;
case 'disconnected':
delete vayakti[j.kunjika];
const index = typing.indexOf(j.kunjika);
if (index > -1) {
typing.splice(index, 1);
}
Messages.pushTypingStatus();
if(!$('#vayakti_model').hasClass('.is-hidden')) refreshVayaktiList();
Messages.pushStatus('Vyakti '+j.name+' disconnected as '+j.kunjika+' at '+Messages.currentTime());
break;
@ -216,6 +224,16 @@ function send() {
autosize($('#send_box')[0]);
}
function sendReaction(emoji, msg_id) {
socket.send(JSON.stringify({
cmd: "react",
msg_id: msg_id,
emoji: emoji
}));
$('#react_bar').remove();
}
function deleteMessages() {
var prop = {
title: 'Delete Messages',

View File

@ -62,48 +62,82 @@ let Messages = class {
scroll.scrollTop(scroll[0].scrollHeight);
}
static pushMessage(sender, text, reply = null, msg_id) {
static pushMessage(sender, appendElm, msg_id) {
var isMe = myinfo.kunjika == sender;
var area = $('#message_area');
var parent = $('<div>');
var elm = $('<div>', {class: 'message '+(isMe?'message-me':'message-other'), msgid: msg_id});
if(!no_name_message) {
elm.append($('<div>', {class: 'message-sub', name: 'by'})
elm.append($('<div>', {class: 'message-sub', name: 'by'})
.append($('<span>').text(vayakti[sender]+'('+sender+')'))
.append($('<span>', {class: 'pull-right'}).text(Messages.currentTime())));
}
if(reply != null && reply.length > 0) {
elm.append(
$('<div>', {class: 'message message-reply'})
.append($('<pre>').text(reply))
);
}
elm.append($('<pre>').text(text));
appendElm.forEach(function(app) {
elm.append(app);
});
elm.click(function() {
Messages.pick(this);
});
area.append(elm);
elm.on('taphold', { delay: 700 },function () {
if(parent.find('#react_bar').length > 0) {
$('#react_bar').remove();
return
} else if($('#react_bar').length > 0) $('#react_bar').remove();
var ee = $('<div>', {id: 'react_bar'});
['like', 'heart', 'laugh', 'sad'].forEach(function(i) {
ee.append($('<button>', {class: 'button', style: 'padding: 1rem'})
.append($('<img>', {src: 'img/'+i+'.svg', height: '18'}))
.click(function(evt) {
sendReaction(i,msg_id);
}));
})
ee.append($('<button>', {class: 'button', style: 'padding: 1rem'})
.append($('<img>', {src: 'img/close.svg', height: '18'}))
.click(function(evt) {
$('#react_bar').remove();
}));
parent.append(ee);
});
parent.append(elm);
area.append(parent);
var scroll = $("#message_area_scroll");
scroll.scrollTop(scroll[0].scrollHeight);
}
static pushImage(sender, src, 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) {
elm.append($('<div>', {class: 'message-sub', name: 'by'})
.append($('<span>').text(vayakti[sender]+'('+sender+')'))
.append($('<span>', {class: 'pull-right'}).text(Messages.currentTime())));
}
elm.append($('<img>', {src: src, width: 300}));
elm.click(function() {
Messages.pick(this);
});
area.append(elm);
static pushText(sender, text, reply = null, msg_id) {
var app = [];
if(reply != null && reply.length > 0) {
app.push(
$('<div>', {class: 'message message-reply'})
.append($('<pre>').text(reply))
);
}
app.push($('<pre>').text(text));
Messages.pushMessage(sender,app,msg_id);
}
var scroll = $("#message_area_scroll");
scroll.scrollTop(scroll[0].scrollHeight);
static pushImage(sender, src, msg_id) {
Messages.pushMessage(sender,[$('<img>', {src: src, width: 300})],msg_id);
}
static addReaction(sender, emoji, msg_id) {
var msg = $('[msgid='+msg_id+']');
console.log('msg', msg, msg_id);
if(msg.find('[name=bar_msg]').length == 0) {
msg.append($('<div>', {class: 'message-sub', name: 'bar_msg'}));
console.log('inside');
}
var bar = msg.find('[name=bar_msg]');
console.log('bar', bar);
var elm = bar.find('[name="r_'+sender+'"]');
if(elm.length > 0) {
elm.find('img').attr('src', 'img/'+emoji+'.svg');
elm.find('span').text(vayakti[sender]+'('+sender+')');
} else {
var elm = $('<span>', {name: 'r_'+sender, style: 'padding: 0px 4px; display: inline-flex'});
elm.append($('<img>', {style: 'height: 1.4rem', src: 'img/'+emoji+'.svg'}));
elm.append($('<span>').text(vayakti[sender]+'('+sender+')'));
bar.append(elm);
}
}
// in message area
@ -116,12 +150,6 @@ let Messages = class {
var scroll = $("#message_area_scroll");
scroll.scrollTop(scroll[0].scrollHeight);
}
static selectedMessageToText() {
return text.trim();
}
static prepareReply() {
var text = "";
@ -214,10 +242,7 @@ let Messages = class {
static editMessages(msgid, text) {
var msg = $('[msgid='+msgid+']');
if(msg.find('[name=edited]').length == 0) {
if(msg.find('[name=bar_msg]').length == 0) {
msg.append($('<div>', {class: 'message-sub', name: 'bar_msg'}));
}
msg.find('[name=bar_msg]').append($('<span>', {name: 'edited'}).text('edited'));
msg.find('[name=by]').append($('<span>', {name: 'edited', class: 'text-grey bd-light', style: 'margin-left: 4px; padding: 0px 3px'}).text('edited'));
}
$('[msgid='+msgid+']').find('pre').last().text(text);
}

82
static/js/taphold.js Normal file
View File

@ -0,0 +1,82 @@
(function ($) {
function namespaced (name, ns) {
return name.replace(/\w+/g, '$&'+ns);
}
var startevent = namespaced(window.PointerEvent ? 'pointerdown' : 'touchstart mousedown', '.taphold');
var preventClick = {
isActive: false,
handler: function (event) {
preventClick.off();
event.stopPropagation();
event.preventDefault();
},
off: function () {
document.removeEventListener('click', preventClick.handler, {capture: true});
$(document).off('.enableclick');
preventClick.isActive = false;
},
on: function () {
if (!preventClick.isActive) {
preventClick.isActive = true;
$(document).on(namespaced(startevent,'.enableclick'), preventClick.off);
// https://stackoverflow.com/a/20290312/2520247
// Note: listeners directly attached to element may skip capture phase
// that's why we add add our click-preventing handler to `document`
document.addEventListener('click', preventClick.handler, {capture: true});
// https://github.com/jquery/jquery/issues/1735
}
}
};
var _cancel = '.taphold.cancel';
var cancelevent = {
pointerdown: namespaced('pointerup pointercancel pointerout', _cancel),
touchstart: namespaced('touchend touchmove touchcancel', _cancel),
mousedown: namespaced('mouseup mouseout dragstart', _cancel)
};
function startHandler (event) {
var data = event.data;
if (event.originalEvent.isPrimary === false) { return; }
if (typeof event.button === 'number') {
if (event.button !== 0) { return; }
} else if (event.touches) {
if (event.touches.length !== 1) { return; }
}
var $elem = $(this);
var _timer = setTimeout(function () {
$elem.off(_cancel);
$elem.triggerHandler($.Event('taphold', {target: event.target}), data);
if (event.type === 'touchstart' || event.pointerType === 'touch') {
// prevent simulated mouse events https://w3c.github.io/touch-events/#mouse-events
$elem.one('touchend', data, function (e) { e.preventDefault(); });
} else {
preventClick.on();
}
}, data.delay);
$elem.on(cancelevent[event.type], data, function () {
$elem.off(_cancel);
clearTimeout(_timer); // cancel taphold
});
}
$.event.special.taphold = {
defaults: {
delay: 500
},
setup: function (data) {
data = $.extend({}, $.event.special.taphold.defaults, data);
$(this).on(startevent, data, startHandler);
},
teardown: function () {
$(this).off('.taphold');
}
};
})(jQuery);