/** * @param {SlackChan|SlackGroup} chan * @return {Element} **/ function createChanListItem(chan) { var dom = document.createElement("li"); dom.id = chan.id; if (chan.id[0] === 'D') dom.className = R.klass.chatList.entry + " " +R.klass.chatList.typeDirect; else if (chan.id[0] === 'G') dom.className = R.klass.chatList.entry + " " +R.klass.chatList.typeGroup; else if (chan.id[0] === 'C') dom.className = R.klass.chatList.entry + " " +R.klass.chatList.typeChannel; dom.textContent = chan.name; return dom; } /** * @param {SlackIms} ims * @return {Element} **/ function createImsListItem(ims) { var dom = document.createElement("li"); dom.id = ims.id; dom.className = R.klass.chatList.entry; dom.textContent = ims.user.name; return dom; } function onContextUpdated() { var chanListFram = document.createDocumentFragment(); var sortedChans = SLACK.context.self ? Object.keys(SLACK.context.self.channels) : []; sortedChans.sort(function(a, b) { if (a[0] !== b[0]) { return a[0] - b[0]; } return (SLACK.context.channels[a] || SLACK.context.groups[a]).name.localeCompare((SLACK.context.channels[b] || SLACK.context.groups[b]).name); }); sortedChans.forEach(function(chanId) { var chan = SLACK.context.channels[chanId] || SLACK.context.groups[chanId] ,chanListItem = createChanListItem(chan); if (chanListItem) { chanListFram.appendChild(chanListItem); } }); var sortedUsers = SLACK.context.users ? Object.keys(SLACK.context.users) : []; sortedUsers.sort(function(a, b) { return SLACK.context.users[a].name.localeCompare(SLACK.context.users[b].name); }); sortedUsers.forEach(function(userId) { var ims = SLACK.context.users[userId].ims ,imsListItem = createImsListItem(ims); if (imsListItem) { chanListFram.appendChild(imsListItem); } }); document.getElementById(R.id.chanList).textContent = ""; document.getElementById(R.id.chanList).appendChild(chanListFram); } function onRoomSelected() { var name = SELECTED_ROOM.name || (SELECTED_ROOM.user ? SELECTED_ROOM.user.name : undefined); if (!name) { var members = []; for (var i in SELECTED_ROOM.members) { members.push(SELECTED_ROOM.members[i].name); } name = members.join(", "); } document.getElementById(R.id.currentRoom.title).textContent = name; onRoomUpdated(); } function createMessageDom(channelId, msg) { var dom = document.createElement("div") ,ts = document.createElement("div") ,text = document.createElement("div") ,author = document.createElement("div") ,authorImg = document.createElement("img") ,authorName = document.createElement("span") ,hover = document.createElement("ul") ,hoverReply = document.createElement("li") ,sender = msg.raw["user"] ? SLACK.context.users[msg.raw["user"]] : SLACK.context.bots[msg.raw["bot_id"]]; dom.id = channelId +"_" +msg.ts; dom.className = R.klass.msg.item; ts.className = R.klass.msg.ts; text.className = R.klass.msg.msg; author.className = R.klass.msg.author; authorImg.className = R.klass.msg.authorAvatar; authorName.className = R.klass.msg.authorname; hover.className = R.klass.msg.hover.container; hoverReply.className = R.klass.msg.hover.reply; ts.textContent = (new Date(msg.ts * 1000)).toLocaleTimeString(); text.textContent = msg.raw["text"]; authorName.textContent = sender ? sender.name : (msg.raw["username"] || "?"); authorImg.src = sender ? sender.icons.image_48 : ""; author.appendChild(authorImg); author.appendChild(authorName); hover.appendChild(hoverReply); dom.appendChild(author); dom.appendChild(text); dom.appendChild(ts); dom.appendChild(hover); return dom; } function onRoomUpdated() { var chatFrag = document.createDocumentFragment() ,currentRoomId = SELECTED_ROOM.id; document.getElementById(R.id.currentRoom.content).textContent = ""; if (SLACK.history[currentRoomId]) SLACK.history[currentRoomId].messages.forEach(function(msg) { chatFrag.appendChild(createMessageDom(currentRoomId, msg)); }); var content = document.getElementById(R.id.currentRoom.content); content.appendChild(chatFrag); //TODO scroll lock console.log(content.scrollTop = content.scrollHeight -content.clientHeight); } function onChanClick(e) { while (e.target !== e.currentTarget && e.target) { if (e.target.classList.contains(R.klass.chatList.entry)) { var room = (SLACK.context.channels[e.target.id] || SLACK.context.ims[e.target.id] || SLACK.context.groups[e.target.id]); if (room && room !== SELECTED_ROOM) { selectRoom(room); } return; } e.target = e.target.parentElement; } } function replyTo(msg) { console.log("Replying to ", msg); } function chatClickDelegate(e) { var target = e.target ,getMessageId = function(e, target) { target = target || e.target; while (target !== e.currentTarget && target) { if (target.classList.contains(R.klass.msg.item)) { return target.id; } target = target.parentElement; } }; while (target !== e.currentTarget && target) { if (target.classList.contains(R.klass.msg.hover.container)) { return; } else if (target.classList.contains(R.klass.msg.hover.reply)) { var messageId = getMessageId(e, target); if (messageId) { messageId = parseFloat(messageId.split("_")[1]); var history = SLACK.history[SELECTED_ROOM.id].messages; for (var i =0, histLen =history.length; i < histLen && history[i].ts <= messageId; i++) { if (history[i].ts === messageId) { replyTo(history[i]); return; } } } return; } target = target.parentElement; } } document.addEventListener('DOMContentLoaded', function() { document.getElementById(R.id.chatList).addEventListener("click", onChanClick); document.getElementById(R.id.currentRoom.content).addEventListener("click", chatClickDelegate); document.getElementById(R.id.message.form).addEventListener("submit", function(e) { e.preventDefault(); var input =document.getElementById(R.id.message.input); if (SELECTED_ROOM && input.value) { sendMsg(SELECTED_ROOM, input.value); input.value = ""; } return false; }); startPolling(); });