(function (root, factory) { if (typeof define === 'function' && define.amd) { define(["converse"], factory); } else { factory(converse); } }(this, function (converse) { var _converse, dayjs, html, _, __; converse.plugins.add("search", { 'dependencies': [], 'initialize': function () { dayjs = converse.env.dayjs; _converse = this._converse; __ = _converse.__ html = converse.env.html; _ = converse.env._; class SearchDialog extends _converse.exports.BaseModal { initialize() { super.initialize(); this.listenTo(this.model, "change", () => this.requestUpdate()); this.addEventListener('shown.bs.modal', () => { if (this.model.get("keyword")) { this.querySelector('#pade-search-keywords').value = this.model.get("keyword"); this.doSearch(); } else { this.keyInput = this.querySelector('#pade-search-keywords'); this.keyInput.focus(); this.keyInput.addEventListener('keyup', (ev) => { this.keyUp(ev); }); this.querySelector('.btn-pdf').addEventListener('click', (ev) => { this.doPDF(ev); }); this.querySelector('.btn-word-cloud').addEventListener('click', (ev) => { this.doWordCloud(ev); }); } }); } getModalTitle () { return __('Search: %1$s', this.model.get('room')); } renderModal() { return html``; } keyUp(ev) { console.debug("keyUp", ev); if (ev.key === "Enter") { var keyword = this.keyInput.value.trim(); this.model.set("keyword", keyword) this.doSearch(); } } doSearch() { console.debug("doSearch"); var view = this.model.get("view"); var jid = view.model.get("jid"); var type = view.model.get("type"); var groupchat = view.model.get("type") == "chatroom"; var method = _converse.api.settings.get("search_method"); var keyword = this.model.get("keyword"); var searchRegExp = undefined; var tagRegExp = undefined; var pdf_body = []; console.debug("doSearch", keyword, jid, groupchat); if (keyword != "") { searchRegExp = new RegExp('^(.*)(\s?' + keyword + ')', 'i'); tagRegExp = new RegExp("(\\b" + keyword + "\\b)", "im"); } var searchResults = this.querySelector("#pade-search-results"); searchResults.innerHTML = "No Match"; var html = ""; if (method == "mam") { _converse.api.archive.query({mam: {'with': jid}, rsm: { before: '', max:999 }, is_groupchat: groupchat}).then((result) => { const messages = result.messages; console.debug("doSearch - messages", messages); for (var i=0; i -1) pdf_body.push([pretty_time, pretty_from, body]); html = html + makeHtml(searchRegExp, tagRegExp, body, pretty_time, pretty_from); } } html = html + "
DatePersonMessage
"; searchResults.innerHTML = html; this.model.set("pdf_body", pdf_body); }); } else { var messages = view.model.messages.models; for (var i=0; i"; searchResults.innerHTML = html; this.model.set("pdf_body", pdf_body); } } doPDF() { const margins = { top: 70, bottom: 40, left: 30, width: 550 }; const pdf = new jsPDF('p','pt','a4'); pdf.autoTable({ head: [['Date', 'Person', 'Message']], body: this.model.get("pdf_body"), columnStyles: { 0: {cellWidth: 100}, 1: {cellWidth: 100}, 2: {cellWidth: 300} } }) const view = this.model.get("view"); const roomLabel = view.model.getDisplayName() || view.model.get("jid"); pdf.save(roomLabel + '.pdf') } doWordCloud() { if (!getSetting("showWordCloud", false)) { debug.error('Enable word cloud and reload application'); return; } let cloudData = ""; const conv = this.model.get("pdf_body") || []; conv.forEach(function(line) { cloudData = cloudData + line[1] + ' ' + line[2] + ' '; }); if (cloudData.length > 0) { const searchResults = this.querySelector("#pade-search-results"); searchResults.innerHTML = ""; searchResults.style.cursor = "pointer"; searchResults.addEventListener("click", function(evt) { searchResults.requestFullscreen(); searchResults.innerHTML = ""; makeWordCloud({ width: screen.availWidth - 50, height: screen.availHeight - 50, font: "Helvetica", container: {element: this, selector: "#pade-search-results"}, words: processData(cloudData) }); }); makeWordCloud({ width: 700, height: 500, font: "Helvetica", container: {element: this, selector: "#pade-search-results"}, words: processData(cloudData) }); } } } _converse.api.elements.define('converse-pade-search-dialog', SearchDialog); _converse.api.settings.extend({ search_method: 'mam' // use values mam or local }); _converse.api.listen.on('getToolbarButtons', function(toolbar_el, buttons) { let style = "width:18px; height:18px; fill:var(--chat-color);"; if (toolbar_el.model.get("type") === "chatroom") { style = "width:18px; height:18px; fill:var(--muc-color);"; } buttons.push(html` `); return buttons; }); _converse.api.listen.on('parseMessageForCommands', function(data, handled) { //console.debug('parseMessageForCommands', data, handled); if (!handled) handled = parseMessageForCommands(data.model, data.text); return handled; }); console.debug("search plugin is ready"); } }); function performSearch(ev) { ev.stopPropagation(); ev.preventDefault(); console.debug('performSearch', ev); const toolbar_el = converse.env.utils.ancestor(ev.target, 'converse-chat-toolbar'); const chatview = _converse.chatboxviews.get(toolbar_el.model.get('jid')); const model = new converse.env.Model(); model.set({ view: chatview}); _converse.api.modal.show('converse-pade-search-dialog', { model }); } function makeHtml(searchRegExp, tagRegExp, body, pretty_time, pretty_from) { let html = ""; if (!searchRegExp || searchRegExp.test(body)) { var tagged = tagRegExp ? body.replace(tagRegExp, "$1") : body; html = html + "" + pretty_time + "" + pretty_from + "" + tagged + ""; } return html; } function processData(strings) { if(!strings) return; // strip stringified objects, common words and punctuations from the string strings = strings.removeStopWords().toLowerCase().replace(/object Object/g, '').replace(/[\+\.,\/#!$%\^&\*{}=_`~]/g,''); // convert the str back in an array strings = strings.split(' '); // Count frequency of word occurance var wordCount = {}; for(var i = 0; i < strings.length; i++) { if(!wordCount[strings[i]]) wordCount[strings[i]] = 0; wordCount[strings[i]]++; // {'hi': 12, 'foo': 2 ...} } console.debug("processData", strings, wordCount); var wordCountArr = []; for(var prop in wordCount) { wordCountArr.push({text: prop, size: wordCount[prop] * 10}); } return wordCountArr; } function makeWordCloud(options) { if(options == undefined) options = {} if(options.width == undefined) options.width = 300 if(options.height == undefined) options.height = 300 if(options.font == undefined) options.font = "Arial" if(options.container == undefined) options.container = "body" if(options.words == undefined) options.words = [{text: "This", size: 40}, {text: "is", size: 40}, {text: "an", size: 40}, {text: "Example", size: 40}] var fill = d3.scale.category20(); d3.layout.cloud().size([options.width, options.height]) .words(options.words) .rotate(function(d) { return ~~(Math.random() * 3) * 45 - 45; }) .font(options.font) .fontSize(function(d) { return d.size; }) .on("end", function(words) { d3.select(options.container.selector, options.container.element).append("svg") .attr("width", options.width) .attr("height", options.height) .append("g") .attr("transform", "translate(" + (options.width/2) + "," + (options.height/2) + ")") .selectAll("text") .data(words) .enter().append("text") .style("font-size", function(d) { return d.size + "px"; }) .style("font-family", options.font) .style("fill", function(d, i) { return fill(i); }) .attr("text-anchor", "middle") .attr("transform", function(d) { return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; }) .text(function(d) { return d.text; }); }) .start(); } function isInViewport (elem) { var distance = elem.getBoundingClientRect(); return ( distance.top >= 0 && distance.left >= 0 && distance.bottom <= (window.innerHeight || document.documentElement.clientHeight) && distance.right <= (window.innerWidth || document.documentElement.clientWidth) ); } function injectMessage(model, title, body) { const msgId = 'inject-' + Math.random().toString(36).substr(2,9); const type = model.get("type") == "chatbox" ? "chat" : "groupchat"; const from = model.get("jid"); let attrs = {message: body, body, id: msgId, msgId, type, from: _converse.jid}; if (type == "groupchat") { attrs = {message: body, body, id: msgId, msgId, type, from_muc: from, from: from + '/' + title, nick: title}; } model.queueMessage(attrs); } function parseMessageForCommands(model, text) { text = text.replace(/^\s*/, ''); const command = (text.match(/^\/([a-zA-Z]*) ?/) || ['']).pop().toLowerCase(); if (!command) { return false; } const args = text.slice(('/' + command).length + 1).trim().split(' ').filter(s => s) || []; //console.debug('parseMessageForCommands', command, args); if (command === "search" && args.length == 1) { const view = _converse.chatboxviews.get(model.get('jid')); searchDialog = new SearchDialog({ 'model': new converse.env.Model({view: view, keyword: args[0]}) }); searchDialog.model.set("keyword", args[0]); searchDialog.show(); return true; } else if (command == "summary") { const title = model.getDisplayName() + " - Summary"; const messages = model.messages.models; let firstMsg = 0; console.debug('parseMessageForCommands - summary', title, messages, args); if (args.length == 0 || args[0] != 'all') { for (let i=0; i')) { detail = detail + "*" + pretty_from + "* says " + body + "\n"; } } const summarizer = new JsSummarize(); const summary = summarizer.summarize('', detail); injectMessage(model, title, summary.join('\n')); return true; } return false; } }));