Merge pull request #27 from Lynxy/master

Add the ability to filter messages by username
This commit is contained in:
Daniel Chýlek 2018-02-16 14:05:34 +01:00 committed by GitHub
commit fa52c3aeb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 119 additions and 4 deletions

View File

@ -32,6 +32,12 @@
</select> </select>
</div> </div>
<div> <!-- needed to stop the select from messing up -->
<select id="opt-messages-by-user">
<option value="">Filter messages by user&nbsp;</option>
</select>
</div>
<div class="nav"> <div class="nav">
<button id="nav-first" data-nav="first">&laquo;</button> <button id="nav-first" data-nav="first">&laquo;</button>
<button id="nav-prev" data-nav="prev">&lsaquo;</button> <button id="nav-prev" data-nav="prev">&lsaquo;</button>

View File

@ -26,6 +26,10 @@ document.addEventListener("DOMContentLoaded", () => {
STATE.setMessagesPerPage(GUI.getOptionMessagesPerPage()); STATE.setMessagesPerPage(GUI.getOptionMessagesPerPage());
GUI.onOptionMessagesByUserChanged(() => {
STATE.setMessagesByUser(GUI.getOptionMessagesByUser());
});
GUI.onNavigationButtonClicked(action => { GUI.onNavigationButtonClicked(action => {
STATE.updateCurrentPage(action); STATE.updateCurrentPage(action);
}); });
@ -39,4 +43,8 @@ document.addEventListener("DOMContentLoaded", () => {
GUI.updateMessageList(messages); GUI.updateMessageList(messages);
GUI.scrollMessagesToTop(); GUI.scrollMessagesToTop();
}); });
STATE.onUsersRefreshed(users => {
GUI.updateUserFilter(users);
});
}); });

View File

@ -1,6 +1,7 @@
var GUI = (function(){ var GUI = (function(){
var eventOnFileUploaded; var eventOnFileUploaded;
var eventOnOptMessagesPerPageChanged; var eventOnOptMessagesPerPageChanged;
var eventOnOptMessagesByUserChanged;
var eventOnNavButtonClicked; var eventOnNavButtonClicked;
var showModal = function(width, html){ var showModal = function(width, html){
@ -73,6 +74,10 @@ var GUI = (function(){
eventOnOptMessagesPerPageChanged && eventOnOptMessagesPerPageChanged(); eventOnOptMessagesPerPageChanged && eventOnOptMessagesPerPageChanged();
}); });
DOM.id("opt-messages-by-user").addEventListener("change", () => {
eventOnOptMessagesByUserChanged && eventOnOptMessagesByUserChanged();
});
DOM.tag("button", DOM.fcls("nav")).forEach(button => { DOM.tag("button", DOM.fcls("nav")).forEach(button => {
button.disabled = true; button.disabled = true;
@ -113,6 +118,13 @@ var GUI = (function(){
eventOnOptMessagesPerPageChanged = callback; eventOnOptMessagesPerPageChanged = callback;
}, },
/*
* Sets a callback for when the user changes the messages by user option. The callback is not passed any arguments.
*/
onOptionMessagesByUserChanged: function(callback){
eventOnOptMessagesByUserChanged = callback;
},
/* /*
* Sets a callback for when the user clicks a navigation button. The callback is passed one of the following strings: first, prev, next, last. * Sets a callback for when the user clicks a navigation button. The callback is passed one of the following strings: first, prev, next, last.
*/ */
@ -131,6 +143,13 @@ var GUI = (function(){
return parseInt(DOM.id("opt-messages-per-page").value, 10); return parseInt(DOM.id("opt-messages-per-page").value, 10);
}, },
/*
* Returns the user which to filter messages by.
*/
getOptionMessagesByUser: function(){
return DOM.id("opt-messages-by-user").value;
},
/* /*
* Updates the navigation text and buttons. * Updates the navigation text and buttons.
*/ */
@ -158,7 +177,7 @@ var GUI = (function(){
eleChannels.innerHTML = ""; eleChannels.innerHTML = "";
} }
else{ else{
eleChannels.innerHTML = channels.map(channel => DISCORD.getChannelHTML(channel)).join(""); eleChannels.innerHTML = channels.filter(channel => channel.msgcount > 0).map(channel => DISCORD.getChannelHTML(channel)).join("");
Array.prototype.forEach.call(eleChannels.children, ele => { Array.prototype.forEach.call(eleChannels.children, ele => {
ele.addEventListener("click", e => { ele.addEventListener("click", e => {
@ -186,6 +205,34 @@ var GUI = (function(){
DOM.id("messages").innerHTML = messages ? messages.map(message => DISCORD.getMessageHTML(message)).join("") : ""; DOM.id("messages").innerHTML = messages ? messages.map(message => DISCORD.getMessageHTML(message)).join("") : "";
}, },
/*
* Updates the select box with all possibly user names.
*/
updateUserFilter: function(users){
var select = DOM.id("opt-messages-by-user");
// Remove all but first option
for (var i = select.length; i > 0; i--) {
select.remove(i);
}
var options = [];
for (var key in users) {
// Skip loop if the property is from prototype
if (!users.hasOwnProperty(key)) continue;
var option = document.createElement("option");
option.value = key;
option.text = users[key].name;
options.push(option);
}
options.sort((a, b) => {
return a.text.toLowerCase().localeCompare(b.text.toLowerCase());
}).forEach(option => {
select.add(option);
});
},
/* /*
* Scrolls the message div to the top. * Scrolls the message div to the top.
*/ */

View File

@ -38,6 +38,16 @@ SAVEFILE.prototype.getMessageCount = function(channel){
return Object.keys(this.getMessages(channel)).length; return Object.keys(this.getMessages(channel)).length;
}; };
SAVEFILE.prototype.getFilteredMessageCount = function(channel, userindex){
if (userindex === -1) return this.getMessageCount(channel);
var count = 0;
UTILS.forEachValue(this.getMessages(channel), messageObject => {
if (messageObject.u === userindex) count++;
});
return count;
};
SAVEFILE.prototype.getAllMessages = function(){ SAVEFILE.prototype.getAllMessages = function(){
var messages = {}; var messages = {};

View File

@ -11,6 +11,7 @@ var STATE = (function(){
var selectedChannel; var selectedChannel;
var currentPage; var currentPage;
var messagesPerPage; var messagesPerPage;
var messagesByUser;
// ---------------------------------- // ----------------------------------
// Channel and message refresh events // Channel and message refresh events
@ -18,6 +19,7 @@ var STATE = (function(){
var eventOnChannelsRefreshed; var eventOnChannelsRefreshed;
var eventOnMessagesRefreshed; var eventOnMessagesRefreshed;
var eventOnUsersRefreshed;
var triggerChannelsRefreshed = function(){ var triggerChannelsRefreshed = function(){
eventOnChannelsRefreshed && eventOnChannelsRefreshed(ROOT.getChannelList()); eventOnChannelsRefreshed && eventOnChannelsRefreshed(ROOT.getChannelList());
@ -27,6 +29,10 @@ var STATE = (function(){
eventOnMessagesRefreshed && eventOnMessagesRefreshed(ROOT.getMessageList()); eventOnMessagesRefreshed && eventOnMessagesRefreshed(ROOT.getMessageList());
}; };
var triggerUsersRefreshed = function(){
eventOnUsersRefreshed && eventOnUsersRefreshed(ROOT.getUserList());
};
ROOT.onChannelsRefreshed = function(callback){ ROOT.onChannelsRefreshed = function(callback){
eventOnChannelsRefreshed = callback; eventOnChannelsRefreshed = callback;
}; };
@ -35,6 +41,10 @@ var STATE = (function(){
eventOnMessagesRefreshed = callback; eventOnMessagesRefreshed = callback;
}; };
ROOT.onUsersRefreshed = function(callback){
eventOnUsersRefreshed = callback;
};
// ------------------------------------ // ------------------------------------
// File upload and basic data retrieval // File upload and basic data retrieval
// ------------------------------------ // ------------------------------------
@ -46,6 +56,7 @@ var STATE = (function(){
triggerChannelsRefreshed(); triggerChannelsRefreshed();
triggerMessagesRefreshed(); triggerMessagesRefreshed();
triggerUsersRefreshed();
}; };
ROOT.getChannelName = function(channel){ ROOT.getChannelName = function(channel){
@ -66,12 +77,13 @@ var STATE = (function(){
ROOT.getChannelList = function(){ ROOT.getChannelList = function(){
var channels = FILE.getChannels(); var channels = FILE.getChannels();
var userindex = messagesByUser ? FILE.meta.userindex.indexOf(messagesByUser) : -1;
return Object.keys(channels).map(key => ({ return Object.keys(channels).map(key => ({
"id": key, "id": key,
"name": channels[key].name, "name": channels[key].name,
"server": FILE.getServer(channels[key].server), "server": FILE.getServer(channels[key].server),
"msgcount": FILE.getMessageCount(key) "msgcount": FILE.getFilteredMessageCount(key, userindex)
})); }));
}; };
@ -90,6 +102,19 @@ var STATE = (function(){
// ------------ // ------------
// Message list // Message list
// ------------ // ------------
ROOT.getFilteredMessageList = function(){
if (!messagesByUser) {
return MSGS;
}
var pos = FILE.meta.userindex.indexOf(messagesByUser);
var messages = FILE.getMessages(selectedChannel);
return MSGS.filter(key => {
var message = messages[key];
return message.u == pos;
});
};
ROOT.getMessageList = function(){ ROOT.getMessageList = function(){
if (!MSGS){ if (!MSGS){
@ -99,7 +124,7 @@ var STATE = (function(){
var messages = FILE.getMessages(selectedChannel); var messages = FILE.getMessages(selectedChannel);
var startIndex = messagesPerPage*(ROOT.getCurrentPage()-1); var startIndex = messagesPerPage*(ROOT.getCurrentPage()-1);
return MSGS.slice(startIndex, !messagesPerPage ? undefined : startIndex+messagesPerPage).map(key => { return ROOT.getFilteredMessageList().slice(startIndex, !messagesPerPage ? undefined : startIndex+messagesPerPage).map(key => {
var message = messages[key]; var message = messages[key];
return { return {
@ -113,6 +138,25 @@ var STATE = (function(){
}); });
}; };
ROOT.getUserList = function(){
if (!FILE){
return [];
}
return FILE.meta.users;
};
// ----------
// Filtering
// ----------
ROOT.setMessagesByUser = function(key){
currentPage = 1;
messagesByUser = key;
triggerChannelsRefreshed();
triggerMessagesRefreshed();
};
// ---------- // ----------
// Pagination // Pagination
// ---------- // ----------
@ -144,7 +188,7 @@ var STATE = (function(){
}; };
ROOT.getPageCount = function(){ ROOT.getPageCount = function(){
return !MSGS ? 0 : (!messagesPerPage ? 1 : Math.ceil(MSGS.length/messagesPerPage)); return !MSGS ? 0 : (!messagesPerPage ? 1 : Math.ceil(ROOT.getFilteredMessageList().length/messagesPerPage));
}; };
// -------- // --------