/* jshint sub: true */ var /** * @type {number} next period to wait before next retry in case of failure, in seconds **/ NEXT_RETRY = 0, /** * @type {Room|null} **/ SELECTED_ROOM = null, /** * @type {SimpleChatSystem|null} **/ SELECTED_CONTEXT = null, /** @type {Message|null} */ REPLYING_TO = null, /** @type {Message|null} */ EDITING = null, /** @const @type {number} */ KEEP_MESSAGES = 100 ; function initHljs() { new HttpRequest("highlight.pack.js") .callbackSuccess(function(code, head, resp) { var script = document.createElement("script"), link = document.createElement("link"); script.innerHTML = resp; script.language = "text/javascript"; link.href = "hljs-androidstudio.css"; link.rel = "stylesheet"; document.head.appendChild(link); document.body.appendChild(script); }) .callbackError(function() { console.error("Failure loading hljs required files"); }) .setTimeout(1000 * 60 * 1) // 1 min timeout .send(); } /** * @param {Room} room * @param {function(boolean)} cb **/ function fetchHistory(room, cb) { new HttpRequest("api/hist?room=" +room.id) .setResponseType(HttpRequestResponseType.JSON) .callbackSuccess(function(code, status, resp) { if (resp) { var history = DATA.history[room.id], updated; if (!history) { history = DATA.history[room.id] = new UiRoomHistory(room, KEEP_MESSAGES, /** @type {Array} */ (resp), Date.now()); updated = true; } else { updated = !!history.pushAll(/** @type {Array} */ (resp), Date.now()); } if (updated) { onMsgReceived(DATA.context.getChannelContext(room.id).getChatContext(), room, /** @type {Array} */ (resp)); if (room === SELECTED_ROOM) onRoomUpdated(); } } }, this) .callback(function() { // TODO ui stop loading }) .send(); } function onConfigUpdated() { if (isObjectEmpty(CONFIG.services)) { Settings.setClosable(false).display(Settings.pages.services); } loadEmojiProvider(CONFIG.getEmojiProvider()); document.getElementById(R.id.stylesheet).innerHTML = CONFIG.compileCSS(); } function poll(callback) { new HttpRequest("api?v=" +DATA.lastServerVersion) .callback(function(statusCode, statusText, resp) { var success = Math.floor(statusCode / 100) === 2; if (success) { if (NEXT_RETRY) { NEXT_RETRY = 0; onNetworkStateUpdated(true); } } else { if (NEXT_RETRY) { NEXT_RETRY += Math.floor((NEXT_RETRY || 5)/2); NEXT_RETRY = Math.min(60, NEXT_RETRY); } else { NEXT_RETRY = 5; onNetworkStateUpdated(false); } } callback(success, resp); }) .setResponseType(HttpRequestResponseType.JSON) .setTimeout(1000 * 60 * 1) .send(); } function outOfSync() { DATA.lastServerVersion = 0; } /** * @param {Room} room **/ function sendTyping(room) { new HttpRequest(HttpRequestMethod.POST, "api/typing?room=" +room.id).send(); } /** * @param {boolean} success * @param {*} response **/ function onPollResponse(success, response) { if (success) { if (response) { DATA.update(response); } startPolling(); } else { setTimeout(startPolling, NEXT_RETRY * 1000); } } function startPolling() { poll(onPollResponse); } /** * @param {Room} room **/ function selectRoom(room) { if (SELECTED_ROOM) unselectRoom(); document.getElementById("room_" +room.id).classList.add(R.klass.selected); document.body.classList.remove(R.klass.noRoomSelected); SELECTED_ROOM = room; SELECTED_CONTEXT = /** @type {SimpleChatSystem} */ (DATA.context.getChannelContext(room.id)); onRoomSelected(); roomInfo.hide(); createContextBackground(SELECTED_CONTEXT.getChatContext().team.id, SELECTED_CONTEXT.getChatContext().users, function(imgData) { document.getElementById(R.id.context).style.backgroundImage = 'url(' +imgData +')'; }); if (!DATA.history[SELECTED_ROOM.id] || DATA.history[SELECTED_ROOM.id].messages.length < KEEP_MESSAGES) fetchHistory(SELECTED_ROOM, function(success) {}); document.getElementById(R.id.mainSection).classList.remove(R.klass.noRoomSelected); } function setRoomFromHashBang() { var hashId = document.location.hash.substr(1), room = DATA.context.getChannel(hashId); if (room && room !== SELECTED_ROOM) selectRoom(room); else { var user = DATA.context.getUser(hashId); if (user && user.privateRoom) selectRoom(user.privateRoom); } } /** * @param {Room} room **/ function starChannel(room) { new HttpRequest(HttpRequestMethod.POST, "api/starChannel?room=" +room.id).send(); } /** * @param {Room} room **/ function unstarChannel(room) { new HttpRequest(HttpRequestMethod.POST, "api/unstarChannel?room=" +room.id).send(); } function unselectRoom() { document.getElementById("room_" +SELECTED_ROOM.id).classList.remove(R.klass.selected); document.getElementById(R.id.mainSection).classList.add(R.klass.noRoomSelected); } /** * @param {Room} chan * @param {string} filename * @param {File} file * @param {function(string?)} callback **/ function uploadFile(chan, filename, file, callback) { var fileReader = new FileReader(), formData = new FormData(); formData.append("file", file); formData.append("filename", filename); new HttpRequest(HttpRequestMethod.POST, "api/file?room=" +chan.id) .callbackSuccess(function() { callback(null); }) .callbackError(function(sCode, sText, resp) { callback(sText); }) .send(formData); } /** * @param {string} payload * @param {string} serviceId * @param {(function((string|null)))=} callback **/ function sendCommand(payload, serviceId, callback) { var xhr = new HttpRequest(HttpRequestMethod.POST, "api/attachmentAction?serviceId=" +serviceId); if (callback) xhr.callbackSuccess(function() { callback(null); }).callbackError(function(code, head, resp) { callback(head); }); xhr.send(JSON.stringify(payload)); } function getActionPayload(channelId, msg, attachment, action) { var payload = { "actions": [ action ], "attachment_id": attachment["id"], "callback_id": attachment["callback_id"], "channel_id": channelId, "is_ephemeral": msg instanceof NoticeMessage, "message_ts": msg["id"] }; return payload; } /** * @param {Room} chan * @param {Command!} cmd * @param {string} args **/ function doCommand(chan, cmd, args) { new HttpRequest(HttpRequestMethod.POST, "api/cmd?room=" +chan.id +"&cmd=" +encodeURIComponent(cmd.name.substr(1)) +"&args=" +encodeURIComponent(args)).send(); } /** * @param {Room} chan * @param {string} msg * @param {Message|null=} replyTo **/ function sendMsg(chan, msg, replyTo) { var url = 'api/msg?room=' +chan.id +"&text=" +encodeURIComponent(msg); if (replyTo) { var sender = DATA.context.getUser(replyTo.userId), footer = chan.isPrivate ? locale.message : chan.name; var attachment = { "fallback": replyTo.text, "author_name": sender.getName(), "text": replyTo.text, "footer": footer, "ts": replyTo.ts }; url += "&attachments=" +encodeURIComponent(JSON.stringify([attachment])); } new HttpRequest(HttpRequestMethod.POST, url).send(); } /** * @param {Room} chan * @param {string} text * @param {Message} msg **/ function editMsg(chan, text, msg) { new HttpRequest(HttpRequestMethod.PUT, "api/msg?room=" +chan.id +"&ts=" +msg.id +"&text=" +encodeURIComponent(text)).send(); } /** * @param {Room} chan * @param {Message} msg **/ function removeMsg(chan, msg) { new HttpRequest(HttpRequestMethod.DELETE, "api/msg?room=" +chan.id +"&ts=" +msg.id).send(); } /** * @param {Room} chan * @param {Message} msg **/ function pinMsg(chan, msg) { new HttpRequest(HttpRequestMethod.POST, "api/pinMsg?room=" +chan.id +"&msgId=" +msg.id).send(); } /** * @param {Room} chan * @param {Message} msg **/ function starMsg(chan, msg) { new HttpRequest(HttpRequestMethod.POST, "api/starMsg?room=" +chan.id +"&msgId=" +msg.id).send(); } /** * @param {Room} chan * @param {Message} msg **/ function unpinMsg(chan, msg) { new HttpRequest(HttpRequestMethod.DELETE, "api/pinMsg?room=" +chan.id +"&msgId=" +msg.id).send(); } /** * @param {Room} chan * @param {Message} msg **/ function unstarMsg(chan, msg) { new HttpRequest(HttpRequestMethod.DELETE, "api/starMsg?room=" +chan.id +"&msgId=" +msg.id).send(); } /** * @param {Room} chan * @param {string} id * @param {number} ts **/ function sendReadMarker(chan, id, ts) { new HttpRequest(HttpRequestMethod.POST, "api/markread?room=" +chan.id +"&id=" +id +"&ts=" +ts).send(); } /** * @param {string} channelId * @param {string} msgId * @param {string} reaction **/ function addReaction(channelId, msgId, reaction) { new HttpRequest(HttpRequestMethod.POST, "api/reaction?room=" +channelId +"&msg=" +msgId +"&reaction=" +encodeURIComponent(reaction)).send(); } /** * @param {string} channelId * @param {string} msgId * @param {string} reaction **/ function removeReaction(channelId, msgId, reaction) { new HttpRequest(HttpRequestMethod.DELETE, "api/reaction?room=" +channelId +"&msg=" +msgId +"&reaction=" +encodeURIComponent(reaction)).send(); } function logout() { new HttpRequest(HttpRequestMethod.POST, "api/logout").send(); document.cookie = "sessID=;Path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT;"; document.location.reload(); } /** * @this {Element} **/ function filterChanList() { var chans = {}, matchingChans = [], val = this.value; DATA.context.foreachChannels(function(chan) { chans[chan.id] = chan.matchString(val, Utils); }); for (var chanId in chans) { var chanDom = document.getElementById("room_" +chanId); if (chanDom) { if (chans[chanId].name + chans[chanId].members + chans[chanId].topic +chans[chanId].purpose) { chanDom.classList.remove(R.klass.hidden); matchingChans.push(chanId); } else { chanDom.classList.add(R.klass.hidden); } } } //TODO sort }