Mercurial > xmpp-account-manager
changeset 25:d9da5c3e305d
Add support for setting some vCard4 fields.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sun, 23 Dec 2018 16:34:30 +0100 |
parents | 6c620e9f7d2c |
children | 28967a0bb1b2 |
files | client.js index.xhtml util.js vcard.js |
diffstat | 4 files changed, 130 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/client.js +++ b/client.js @@ -126,6 +126,7 @@ document.addEventListener('DOMContentLoa initPEP(connection); initNickname(connection); initAvatar(connection); + initVCard(connection); initMAM(connection); }
--- a/index.xhtml +++ b/index.xhtml @@ -92,6 +92,35 @@ Enter your nickname, so people you know </div> </div> +<hr class="tab-profile"/> + +<div class="row tab-profile"> +<div class="col-sm-4"> +<h2>vCard</h2> +<p>Who are you?</p> +<img width="24" height="24" id="vcard-spinner" hidden=""/> +</div> +<div class="col-sm-8"> +<p> +<label>Full name<br/> +<input id="vcard-fullname" disabled=""/></label><br/> +Enter your name, so people you know can recognize you. +</p> +<p> +<label>Email<br/> +<input id="vcard-email" disabled=""/></label><br/> +This can be used if you forget your password. +</p> +<p> +<label>Who can see your vCard?<br/> +<select id="vcard-access"> +<option value="open">Anyone</option> +<option value="presence">Only your contacts</option> +</select></label> <img width="24" height="24" id="vcard-access-spinner" hidden=""/> +</p> +</div> +</div> + <div class="row tab-account" hidden=""> <div class="col-sm-4"> <h2>Contact list</h2> @@ -189,6 +218,7 @@ Enter your nickname, so people you know <script src="client.js"/> <script src="nickname.js"/> <script src="avatar.js"/> +<script src="vcard.js"/> <script src="pep.js"/> <script src="roster.js"/> <script src="mam.js"/>
--- a/util.js +++ b/util.js @@ -9,6 +9,7 @@ const NS = { avatar_metadata: 'urn:xmpp:avatar:metadata', avatar_data: 'urn:xmpp:avatar:data', nickname: 'http://jabber.org/protocol/nick', + vcard4: 'urn:ietf:params:xml:ns:vcard-4.0', mam: 'urn:xmpp:mam:2', forward: 'urn:xmpp:forward:0', }; @@ -27,6 +28,14 @@ function parseXPath(elem, xpath, result) return value; } +function parseXPathText(elem, xpath) +{ + const value = parseXPath(elem, xpath); + if (value === null) + return null; + return value.textContent; +} + function configurePEPField(node, key, value, cb, err_cb) { return $iq({type: 'set'}) .c('pubsub', {xmlns: 'http://jabber.org/protocol/pubsub#owner'})
new file mode 100644 --- /dev/null +++ b/vcard.js @@ -0,0 +1,90 @@ +'use strict'; + +function initVCard(connection) { + const vcard_access = document.getElementById('vcard-access'); + const vcard_fullname = document.getElementById('vcard-fullname'); + const vcard_email = document.getElementById('vcard-email'); + const spinner_img = document.getElementById('vcard-spinner'); + const access_spinner_img = document.getElementById('vcard-access-spinner'); + + const vcard_data = {}; + + const iq = $iq({type: 'get'}) + .c('pubsub', {xmlns: 'http://jabber.org/protocol/pubsub'}) + .c('items', {node: 'urn:xmpp:vcard4'}) + .c('item', {id: 'current'}); + connection.sendIQ(iq, onVCard4, onVCard4RetrievalError.bind(null, 'PubSub query failed.')); + displaySpinner(spinner_img); + + function onVCard4(result_iq) + { + const item = parseXPath(result_iq, './pubsub:pubsub/pubsub:items/pubsub:item'); + if (item === null) + return onVCard4RetrievalError('no item found.'); + const vcard = parseXPath(item, './vcard4:vcard'); + if (vcard === null) + return onVCard4RetrievalError('no vCard4 found, your PubSub node is broken.'); + + vcard_data.fn = parseXPathText(vcard, './vcard4:fn/vcard4:text'); + vcard_data.email = parseXPathText(vcard, './vcard4:email/vcard4:text'); + + vcard_fullname.value = vcard_data.fn; + vcard_fullname.disabled = false; + vcard_email.value = vcard_data.email; + vcard_email.disabled = false; + hideSpinner(spinner_img); + } + + function onVCard4RetrievalError(string) + { + console.log('Failed to retrieve vCard4: ' + string); + vcard_fullname.disabled = false; + vcard_email.disabled = false; + hideSpinner(spinner_img); + } + + function setVCard4() { + // TODO: avoid overriding fields we don’t understand. + const iq = $iq({type: 'set'}) + .c('vcard', {xmlns: 'urn:ietf:params:xml:ns:vcard-4.0'}) + .c('fn') + .c('text').t(vcard_fullname.value).up().up() + .c('email') + .c('text').t(vcard_email.value).up().up() + connection.sendIQ(iq, onVCard4Changed, onVCard4ChangeError.bind(null, 'coucou')); + displaySpinner(spinner_img); + } + + vcard_fullname.addEventListener('blur', setVCard4); + vcard_email.addEventListener('blur', setVCard4); + + function onVCard4Changed(result_iq) + { + console.log('Successfully set vCard4.') + spinnerOk(spinner_img); + } + + function onVCard4ChangeError(string) + { + console.log('Failed to set vCard4: ' + string); + spinnerError(spinner_img); + } + + vcard_access.addEventListener('change', function (evt) { + const iq = configurePEPField('urn:xmpp:vcard4', 'pubsub#access_model', evt.target.value); + connection.sendIQ(iq, onAccessConfigured, onAccessConfigureError.bind(null, 'PubSub configuration failed.')); + displaySpinner(access_spinner_img); + }); + + function onAccessConfigured(result_iq) + { + console.log('Successfully set vCard4 access model.') + spinnerOk(access_spinner_img); + } + + function onAccessConfigureError(string) + { + console.log('Failed to configure vCard4 node: ' + string); + spinnerError(access_spinner_img); + } +}