Mercurial > xmpp-account-manager
changeset 4:5e97e1808a35
Add support for the roster.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 22 Dec 2018 02:59:29 +0100 |
parents | 5aa1bf7154b0 |
children | cd0434bb2eb1 |
files | client.js index.xhtml roster.js util.js |
diffstat | 4 files changed, 106 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/client.js +++ b/client.js @@ -76,16 +76,12 @@ document.addEventListener('DOMContentLoa pass_element.disabled = true; } else if (status == Strophe.Status.CONNFAIL) { console.log('Strophe failed to connect.'); - connect_button.value = 'connect'; - jid_element.disabled = false; - pass_element.disabled = false; + onDisconnected(); } else if (status == Strophe.Status.DISCONNECTING) { console.log('Strophe is disconnecting.'); } else if (status == Strophe.Status.DISCONNECTED) { console.log('Strophe is disconnected.'); - connect_button.value = 'connect'; - jid_element.disabled = false; - pass_element.disabled = false; + onDisconnected(); } else if (status == Strophe.Status.CONNECTED) { console.log('Strophe is connected.'); onConnected(); @@ -95,8 +91,22 @@ document.addEventListener('DOMContentLoa function onConnected() { connected_div.hidden = false; + initRoster(connection); initPEP(connection); initNickname(connection); initAvatar(connection); } + + function onDisconnected() + { + connect_button.value = 'connect'; + jid_element.disabled = false; + pass_element.disabled = false; + for (let item of document.getElementById('roster-table')) { + item.remove(); + } + for (let item of document.getElementById('pep-table')) { + item.remove(); + } + } });
--- a/index.xhtml +++ b/index.xhtml @@ -62,6 +62,13 @@ <option value="presence">Only your contacts</option> </select></label> </p> +<h2>Contact list</h2> +<table> +<thead> +<tr><th>JID</th><th>Name</th><th>Subscription</th><th>Groups</th><th>⚠️ Delete</th></tr> +</thead> +<tbody id="roster-table"/> +</table> <h2>PEP</h2> <table> <thead> @@ -106,6 +113,7 @@ <script src="nickname.js"/> <script src="avatar.js"/> <script src="pep.js"/> +<script src="roster.js"/> </body> </html>
new file mode 100644 --- /dev/null +++ b/roster.js @@ -0,0 +1,81 @@ +'use strict'; + +function initRoster(connection) { + const roster_table = document.getElementById('roster-table'); + + const iq = $iq({type: 'get'}) + .c('query', {xmlns: NS.roster}); + connection.sendIQ(iq, onRoster, onRosterError.bind(null, 'roster query failed.')); + + function onRoster(result_iq) + { + const items = parseXPath(result_iq, './roster:query/roster:item', XPathResult.ORDERED_NODE_ITERATOR_TYPE); + while (true) { + const item = items.iterateNext(); + if (!item) + break; + const jid = item.getAttributeNS(null, 'jid'); + const subscription = item.getAttributeNS(null, 'subscription'); + const name = item.getAttributeNS(null, 'name'); + const groups = item.children; + const tr = document.createElementNS('http://www.w3.org/1999/xhtml', 'tr'); + let td = document.createElementNS('http://www.w3.org/1999/xhtml', 'td'); + const a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a'); + a.setAttributeNS(null, 'href', 'xmpp:' + jid); + a.textContent = jid; + td.appendChild(a); + tr.appendChild(td); + td = document.createElementNS('http://www.w3.org/1999/xhtml', 'td'); + const input = document.createElementNS('http://www.w3.org/1999/xhtml', 'input'); + input.value = name; + input.onblur = function (evt) { + const iq = $iq({type: 'set'}) + .c('query', {xmlns: NS.roster}) + .c('item', {jid: jid, name: evt.target.value}); + for (let group of groups) + iq.c('group').t(group.textContent).up(); + connection.sendIQ(iq, onRosterSet, onRosterSetError.bind(null, 'Roster set failed.')); + }; + td.appendChild(input); + tr.appendChild(td); + td = document.createElementNS('http://www.w3.org/1999/xhtml', 'td'); + td.textContent = subscription; + tr.appendChild(td); + td = document.createElementNS('http://www.w3.org/1999/xhtml', 'td'); + for (let group of groups) { + const span = document.createElementNS('http://www.w3.org/1999/xhtml', 'span'); + // TODO: use a tag system for the UI. + span.textContent = group.textContent; + td.appendChild(span); + } + tr.appendChild(td); + td = document.createElementNS('http://www.w3.org/1999/xhtml', 'td'); + const button = document.createElementNS('http://www.w3.org/1999/xhtml', 'button'); + button.textContent = 'Remove this contact'; + button.onclick = function (evt) { + const iq = $iq({type: 'set'}) + .c('query', {xmlns: NS.roster}) + .c('item', {jid: jid, subscription: 'unsubscribe'}); + connection.sendIQ(iq, onRosterSet.bind(node), onRosterSetError.bind(node, 'contact removal failed.')); + }; + td.appendChild(button); + tr.appendChild(td); + roster_table.appendChild(tr); + } + } + + function onRosterError(string) + { + console.log('Failed to retrieve your contact list: ' + string); + } + + function onRosterSet(result_iq) + { + console.log(result_iq); + } + + function onRosterSetError(string) + { + console.log('Failed to retrieve your contact list: ' + string); + } +}