diff --git a/templates/channeloptions.pug b/templates/channeloptions.pug
index 3527dd87..dfff94e1 100644
--- a/templates/channeloptions.pug
+++ b/templates/channeloptions.pug
@@ -179,12 +179,22 @@ mixin emotes
.form-group
.col-sm-8.col-sm-offset-4
button#cs-emotes-newsubmit.btn.btn-primary Create Emote
- table.table.table-striped.table-condensed
+ form.form-inline
+ .form-group
+ input.emotelist-search.form-control(type="text", placeholder="Search")
+ .form-group
+ .checkbox
+ label
+ input.emotelist-alphabetical(type="checkbox")
+ | Sort alphabetically
+ .emotelist-paginator-container
+ table.emotelist-table.table.table-striped.table-condensed
thead
tr
th Delete
th Name
th Image
+ tbody
button#cs-emotes-export.btn.btn-default Export emote list
button#cs-emotes-import.btn.btn-default Import emote list
diff --git a/www/js/callbacks.js b/www/js/callbacks.js
index 30223e80..c732e1ce 100644
--- a/www/js/callbacks.js
+++ b/www/js/callbacks.js
@@ -969,10 +969,8 @@ Callbacks = {
emoteList: function (data) {
loadEmotes(data);
- var tbl = $("#cs-emotes table");
- tbl.data("entries", data);
- formatCSEmoteList();
EMOTELIST.handleChange();
+ CSEMOTELIST.handleChange();
},
updateEmote: function (data) {
@@ -982,15 +980,16 @@ Callbacks = {
if (CHANNEL.emotes[i].name === data.name) {
found = true;
CHANNEL.emotes[i] = data;
- formatCSEmoteList();
break;
}
}
if (!found) {
CHANNEL.emotes.push(data);
- formatCSEmoteList();
}
+
+ EMOTELIST.handleChange();
+ CSEMOTELIST.handleChange();
},
removeEmote: function (data) {
diff --git a/www/js/util.js b/www/js/util.js
index d2564c40..11ca1072 100644
--- a/www/js/util.js
+++ b/www/js/util.js
@@ -2477,58 +2477,6 @@ function formatCSChatFilterList() {
});
}
-function formatCSEmoteList() {
- var tbl = $("#cs-emotes table");
- tbl.find("tbody").remove();
- var entries = CHANNEL.emotes || [];
- entries.forEach(function (f) {
- var tr = $("
").appendTo(tbl);
- var del = $("").addClass("btn btn-xs btn-danger")
- .appendTo($(" | ").appendTo(tr));
- $("").addClass("glyphicon glyphicon-trash").appendTo(del);
- del.click(function () {
- socket.emit("removeEmote", f);
- });
- var name = $("
").text(f.name).addClass("linewrap")
- .appendTo($(" | ").appendTo(tr));
- var image = $("
").text(f.image).addClass("linewrap")
- .appendTo($(" | ").appendTo(tr));
- image.popover({
- html: true,
- trigger: "hover",
- content: ''
- });
-
- image.click(function () {
- var td = image.parent();
- td.find(".popover").remove();
- image.detach();
- var edit = $("").addClass("form-control").attr("type", "text")
- .appendTo(td);
-
- edit.val(f.image);
- edit.focus();
-
- var finish = function () {
- var val = edit.val();
- edit.remove();
- image.appendTo(td);
- socket.emit("updateEmote", {
- name: f.name,
- image: val
- });
- };
-
- edit.blur(finish);
- edit.keydown(function (ev) {
- if (ev.keyCode === 13) {
- finish();
- }
- });
- });
- });
-}
-
function formatTime(sec) {
var h = Math.floor(sec / 3600) + "";
var m = Math.floor((sec % 3600) / 60) + "";
@@ -3066,6 +3014,105 @@ function onEmoteClicked(emote) {
window.EMOTELIST = new EmoteList("#emotelist", onEmoteClicked);
window.EMOTELIST.sortAlphabetical = USEROPTS.emotelist_sort;
+function CSEmoteList(selector) {
+ EmoteList.call(this, selector);
+}
+
+CSEmoteList.prototype = Object.create(EmoteList.prototype);
+
+CSEmoteList.prototype.loadPage = function (page) {
+ var tbody = this.table.children[1];
+ tbody.innerHTML = "";
+
+ var start = page * this.itemsPerPage;
+ if (start >= this.emotes.length) {
+ return;
+ }
+ var end = Math.min(start + this.itemsPerPage, this.emotes.length);
+ var self = this;
+ this.page = page;
+
+ for (var i = start; i < end; i++) {
+ var row = document.createElement("tr");
+ tbody.appendChild(row);
+
+ (function (emote) {
+ // Add delete button
+ var tdDelete = document.createElement("td");
+ var btnDelete = document.createElement("button");
+ btnDelete.className = "btn btn-xs btn-danger";
+ var pennJillette = document.createElement("span");
+ pennJillette.className = "glyphicon glyphicon-trash";
+ btnDelete.appendChild(pennJillette);
+ tdDelete.appendChild(btnDelete);
+ row.appendChild(tdDelete);
+
+ btnDelete.onclick = function deleteEmote() {
+ document.getElementById("cs-emotes-newname").value = emote.name;
+ document.getElementById("cs-emotes-newimage").value = emote.image;
+ socket.emit("removeEmote", emote);
+ };
+
+ // Add emote name
+ // TODO: editable
+ var tdName = document.createElement("td");
+ var nameDisplay = document.createElement("code");
+ nameDisplay.textContent = emote.name;
+ tdName.appendChild(nameDisplay);
+ row.appendChild(tdName);
+
+ // Add emote image
+ var tdImage = document.createElement("td");
+ var urlDisplay = document.createElement("code");
+ urlDisplay.textContent = emote.image;
+ tdImage.appendChild(urlDisplay);
+ row.appendChild(tdImage);
+
+ // Add popover to display the image
+ var $urlDisplay = $(urlDisplay);
+ $urlDisplay.popover({
+ html: true,
+ trigger: "hover",
+ content: ''
+ });
+
+ // Change the image for an emote
+ $urlDisplay.click(function (clickEvent) {
+ $(tdImage).find(".popover").remove();
+ $urlDisplay.detach();
+
+ var editInput = document.createElement("input");
+ editInput.className = "form-control";
+ editInput.type = "text";
+ editInput.value = emote.image;
+ tdImage.appendChild(editInput);
+ editInput.focus();
+
+ function save() {
+ var val = editInput.value;
+ tdImage.removeChild(editInput);
+ tdImage.appendChild(urlDisplay);
+
+ socket.emit("updateEmote", {
+ name: emote.name,
+ image: val
+ });
+ }
+
+ editInput.onblur = save;
+ editInput.onkeyup = function (event) {
+ if (event.keyCode === 13) {
+ save();
+ }
+ };
+ });
+ })(this.emotes[i]);
+ }
+};
+
+window.CSEMOTELIST = new CSEmoteList("#cs-emotes");
+window.CSEMOTELIST.sortAlphabetical = USEROPTS.emotelist_sort;
+
function showChannelSettings() {
hidePlayer();
$("#channeloptions").on("hidden.bs.modal", function () {