Add emoji/nick/commands/chan autocomplete

This commit is contained in:
Yash Srivastav 2016-12-11 05:43:26 +05:30
parent e3bd30b05f
commit 785842cde5
No known key found for this signature in database
GPG key ID: 67A09FFAC003E189
6 changed files with 1582 additions and 12 deletions

View file

@ -1486,7 +1486,8 @@ kbd {
background: transparent;
}
#context-menu {
#context-menu,
.textcomplete-menu {
position: absolute;
list-style: none;
margin: 0;
@ -1505,7 +1506,8 @@ kbd {
background-color: rgba(0, 0, 0, .1);
}
.context-menu-item {
.context-menu-item,
.textcomplete-item {
cursor: pointer;
display: block;
padding: 4px 8px;
@ -1514,15 +1516,38 @@ kbd {
margin-bottom: 6px;
}
.context-menu-item:hover {
.context-menu-item:hover,
.textcomplete-item:hover,
.textcomplete-menu .active {
background-color: #f6f6f6;
}
.context-menu-item:before {
.context-menu-item:before,
.textcomplete-item:before {
width: 20px;
display: inline-block;
}
.textcomplete-item {
border-bottom-color: rgba(0, 0, 0, .1);
border-bottom-style: solid;
border-bottom-width: 1px;
margin-top: 0;
margin-bottom: 0;
padding: 10px 8px;
}
.textcomplete-item a {
color: #333;
}
.textcomplete-item .emoji {
margin-right: 8px;
width: 16px;
text-align: center;
display: inline-block;
}
/**
* Tooltips v0.5.3
* See http://primercss.io/tooltips/

View file

@ -34,7 +34,7 @@ import jQuery from "jquery";
var key = e.which;
switch (key) {
case 13: // Enter
if (e.shiftKey) {
if (e.shiftKey || self.data("autocompleting")) {
return; // multiline input
}

File diff suppressed because it is too large Load diff

View file

@ -2,12 +2,14 @@
// vendor libraries
require("jquery-ui/ui/widgets/sortable");
require("jquery-textcomplete");
const $ = require("jquery");
const moment = require("moment");
const Mousetrap = require("mousetrap");
const URI = require("urijs");
// our libraries
const emojiMap = require("./libs/simplemap.json");
require("./libs/jquery/inputhistory");
require("./libs/jquery/stickyscroll");
require("./libs/jquery/tabcomplete");
@ -41,6 +43,80 @@ $(function() {
var favicon = $("#favicon");
// Autocompletion Strategies
var emojiStrategy = {
id: "emoji",
match: /\B:([-+\w]*)$/,
search: function(term, callback) {
callback($.map(Object.keys(emojiMap), function(e) {
return e.indexOf(term) === 0 ? e : null;
}));
},
template: function(value) {
return `<span class="emoji">${emojiMap[value]}</span> ${value}`;
},
replace: function(value) {
return emojiMap[value];
},
index: 1
};
var nicksStrategy = {
id: "nicks",
match: /\B(@([a-zA-Z_[\]\\^{}|`@][a-zA-Z0-9_[\]\\^{}|`-]*)?)$/,
search: function(term, callback) {
term = term.slice(1);
if (term[0] === "@") {
callback(completeNicks(term.slice(1)).map(function(val) {
return "@" + val;
}));
} else {
callback(completeNicks(term));
}
},
template: function(value) {
if (value[0] === "@") {
return value;
}
return "@" + value;
},
replace: function(value) {
return value;
},
index: 1
};
var chanStrategy = {
id: "chans",
match: /\B((#|\+|&|![A-Z0-9]{5})([^\x00\x0A\x0D\x20\x2C\x3A]+(:[^\x00\x0A\x0D\x20\x2C\x3A]*)?)?)$/,
search: function(term, callback, match) {
callback(completeChans(match[0]));
},
template: function(value) {
return value;
},
replace: function(value) {
return value;
},
index: 1
};
var commandStrategy = {
id: "commands",
match: /^\/(\w*)$/,
search: function(term, callback) {
callback(completeCommands("/" + term));
},
template: function(value) {
return value;
},
replace: function(value) {
return value;
},
index: 1
};
socket.on("auth", function(data) {
var login = $("#sign-in");
var token;
@ -638,7 +714,18 @@ $(function() {
chat.find(".chan.active .chat").trigger("msg.sticky"); // fix growing
})
.tab(complete, {hint: false});
.tab(completeNicks, {hint: false})
.textcomplete([emojiStrategy, nicksStrategy, chanStrategy, commandStrategy], {
dropdownClassName: "textcomplete-menu",
placement: "top"
}).on({
"textComplete:show": function() {
$(this).data("autocompleting", true);
},
"textComplete:hide": function() {
$(this).data("autocompleting", false);
}
});
var focus = $.noop;
if (!("ontouchstart" in window || navigator.maxTouchPoints > 0)) {
@ -1272,14 +1359,31 @@ $(function() {
.find(".messages .msg, .date-marker").remove();
}
function complete(word) {
var words = constants.commands.slice();
function completeNicks(word) {
var users = chat.find(".active").find(".users");
var nicks = users.data("nicks");
var words = users.data("nicks");
for (var i in nicks) {
words.push(nicks[i]);
}
return $.grep(
words,
function(w) {
return !w.toLowerCase().indexOf(word.toLowerCase());
}
);
}
function completeCommands(word) {
var words = constants.commands.slice();
return $.grep(
words,
function(w) {
return !w.toLowerCase().indexOf(word.toLowerCase());
}
);
}
function completeChans(word) {
var words = [];
sidebar.find(".chan")
.each(function() {

View file

@ -49,6 +49,7 @@
"express-handlebars": "3.0.0",
"fs-extra": "2.1.2",
"irc-framework": "2.8.0",
"json-loader": "0.5.4",
"ldapjs": "1.0.1",
"lodash": "4.17.4",
"moment": "2.18.1",
@ -68,6 +69,7 @@
"handlebars": "4.0.6",
"handlebars-loader": "1.5.0",
"jquery": "3.2.1",
"jquery-textcomplete": "1.8.0",
"jquery-ui": "1.12.1",
"mocha": "3.3.0",
"mousetrap": "1.6.1",

View file

@ -13,6 +13,7 @@ let config = {
"js/bundle.vendor.js": [
"handlebars/runtime",
"jquery",
"jquery-textcomplete",
"jquery-ui/ui/widgets/sortable",
"moment",
"mousetrap",
@ -46,6 +47,10 @@ let config = {
}
}
},
{
test: /\.json$/,
loader: "json-loader"
},
{
test: /\.tpl$/,
include: [