Commit e7e4f662 authored by Vivek's avatar Vivek

jabberclient: made offline contacts visible. added password reset. updated error handling.

parent c18d9b9e
...@@ -135,8 +135,9 @@ ...@@ -135,8 +135,9 @@
<ul data-role="listview" data-inset="true">\n <ul data-role="listview" data-inset="true">\n
{{#each contact}}\n {{#each contact}}\n
<li>\n <li>\n
{{#if status}}\n
{{#if url}}\n {{#if url}}\n
<a href="{{url}}">\n <a href="{{url}}" class="ui-btn ui-btn-icon-left ui-icon-check">\n
{{#if new_message}}\n {{#if new_message}}\n
<span class="ui-li-count">!</span>\n <span class="ui-li-count">!</span>\n
{{/if}}\n {{/if}}\n
...@@ -144,6 +145,17 @@ ...@@ -144,6 +145,17 @@
{{else}}\n {{else}}\n
{{jid}}\n {{jid}}\n
{{/if}}\n {{/if}}\n
{{else}}\n
{{#if url}}\n
<a href="{{url}}" class="ui-btn ui-btn-icon-left ui-icon-forbidden">\n
{{#if new_message}}\n
<span class="ui-li-count">!</span>\n
{{/if}}\n
{{jid}}</a>\n
{{else}}\n
{{jid}}\n
{{/if}}\n
{{/if}}\n
</li>\n </li>\n
{{/each}}\n {{/each}}\n
</ul>\n </ul>\n
...@@ -207,10 +219,37 @@ ...@@ -207,10 +219,37 @@
</div>\n </div>\n
</script>\n </script>\n
\n \n
<script class="reset-password-template" type="text/x-handlebars-template">\n
<div class="ui-grid-b ui-responsive">\n
<div class="ui-block-a"></div>\n
<div class="ui-block-b">\n
<h2>Reset Password</h2>\n
<form class="reset-password-form">\n
<div class="ui-field-contain">\n
<label>Server URL</label>\n
<input type="text" name="server" placeholder="Server URL" value="tiolive.com" required>\n
</div>\n
<div class="ui-field-contain">\n
<label>New Password</label>\n
<input type="password" name="new_passwd" placeholder="New Password" value="" required>\n
</div>\n
<div class="ui-field-contain">\n
<label>Repeat Password</label>\n
<input type="password" name="repeat_passwd" placeholder="Repeat Password" value="" required>\n
</div>\n
<input data-inline="true" type="submit" value="Submit" data-theme="b">\n
</form>\n
<pre style="white-space: pre-wrap;">{{message}}</pre>\n
</div>\n
<div class="ui-block-c">\n
</div>\n
</div>\n
</script>\n
<script class="message-template" type="text/x-handlebars-template"><li data-theme="{{theme}}" style="{{style}}"><pre style="white-space: pre-wrap;">{{text}}</pre></li></script>\n <script class="message-template" type="text/x-handlebars-template"><li data-theme="{{theme}}" style="{{style}}"><pre style="white-space: pre-wrap;">{{text}}</pre></li></script>\n
\n \n
<script class="history-template" type="text/x-handlebars-template"><pre style="white-space: pre-wrap;">{{text}}</pre></script>\n <script class="history-template" type="text/x-handlebars-template"><pre style="white-space: pre-wrap;">{{text}}</pre></script>\n
\n \n
<script class="error-template" type="text/x-handlebars-template"><pre style="white-space: pre-wrap;">{{error_message}}</pre></script>\n
<script class="header-template" type="text/x-handlebars-template">\n <script class="header-template" type="text/x-handlebars-template">\n
{{#if left_url}}\n {{#if left_url}}\n
<a href="{{left_url}}" class="ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all">{{left_title}}</a>\n <a href="{{left_url}}" class="ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all">{{left_title}}</a>\n
...@@ -368,7 +407,7 @@ ...@@ -368,7 +407,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>klaus.woelfel</string> </value> <value> <string>zope</string> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -382,7 +421,7 @@ ...@@ -382,7 +421,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>942.15924.54448.8823</string> </value> <value> <string>944.5553.6477.32460</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -400,8 +439,8 @@ ...@@ -400,8 +439,8 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1428669417.76</float> <float>1435739472.1</float>
<string>UTC</string> <string>GMT</string>
</tuple> </tuple>
</state> </state>
</object> </object>
......
...@@ -124,6 +124,7 @@ ...@@ -124,6 +124,7 @@
PAGE_DIALOG = "dialog",\n PAGE_DIALOG = "dialog",\n
PAGE_HISTORY = "history",\n PAGE_HISTORY = "history",\n
PAGE_NEW_CONTACT = "subscribe",\n PAGE_NEW_CONTACT = "subscribe",\n
PAGE_PASSWORD = "password",\n
DEFAULT_PAGE = PAGE_CONTACT,\n DEFAULT_PAGE = PAGE_CONTACT,\n
CONNECTION_GADGET_URL = "./gadget_jabberconnection.html",\n CONNECTION_GADGET_URL = "./gadget_jabberconnection.html",\n
CONNECTION_GADGET_SCOPE = "connection",\n CONNECTION_GADGET_SCOPE = "connection",\n
...@@ -139,6 +140,10 @@ ...@@ -139,6 +140,10 @@
result = -1;\n result = -1;\n
} else if (b.new_message && (!a.new_message)) {\n } else if (b.new_message && (!a.new_message)) {\n
result = 1;\n result = 1;\n
} else if (a.status && (!b.status)) {\n
result = -1;\n
} else if (b.status && (!a.status)) {\n
result = 1;\n
} else if (b.jid < a.jid) {\n } else if (b.jid < a.jid) {\n
result = 1;\n result = 1;\n
} else if (a.jid < b.jid) {\n } else if (a.jid < b.jid) {\n
...@@ -149,6 +154,13 @@ ...@@ -149,6 +154,13 @@
return result;\n return result;\n
}\n }\n
\n \n
function validatePassword(password1, password2) {\n
if(password1 === password2) {\n
return true;\n
} else {\n
return false;\n
}\n
}\n
function initializeContact(gadget, jid) {\n function initializeContact(gadget, jid) {\n
if (!(gadget.props.contact_dict.hasOwnProperty(jid))) {\n if (!(gadget.props.contact_dict.hasOwnProperty(jid))) {\n
gadget.props.contact_dict[jid] = {\n gadget.props.contact_dict[jid] = {\n
...@@ -296,39 +308,36 @@ ...@@ -296,39 +308,36 @@
return RSVP.Queue()\n return RSVP.Queue()\n
.push(function () {\n .push(function () {\n
var promise_list = [\n var promise_list = [\n
gadget.aq_pleasePublishMyState({page: PAGE_PASSWORD}),\n
gadget.aq_pleasePublishMyState({page: PAGE_NEW_CONTACT})\n gadget.aq_pleasePublishMyState({page: PAGE_NEW_CONTACT})\n
],\n ],\n
key;\n key;\n
for (key in contact_dict) {\n for (key in contact_dict) {\n
if (contact_dict.hasOwnProperty(key) &&\n
((!contact_dict[key].offline) || (!contact_dict[key].read))) {\n
promise_list.push(\n promise_list.push(\n
gadget.aq_pleasePublishMyState({page: PAGE_DIALOG, jid: key})\n gadget.aq_pleasePublishMyState({page: PAGE_DIALOG, jid: key})\n
);\n );\n
}\n }\n
}\n
return RSVP.all(promise_list);\n return RSVP.all(promise_list);\n
})\n })\n
.push(function (result_list) {\n .push(function (result_list) {\n
var i = 1,\n var i = 2,\n
parameter = {contact: []},\n parameter = {contact: []},\n
key2;\n key2;\n
for (key2 in contact_dict) {\n for (key2 in contact_dict) {\n
if (contact_dict.hasOwnProperty(key2) &&\n
((!contact_dict[key2].offline) || (!contact_dict[key2].read))) {\n
parameter.contact.push({\n parameter.contact.push({\n
jid: key2,\n jid: key2,\n
url: result_list[i],\n url: result_list[i],\n
new_message: !contact_dict[key2].read\n new_message: !contact_dict[key2].read,\n
status: !contact_dict[key2].offline\n
});\n });\n
i += 1;\n i += 1;\n
}\n }\n
}\n
parameter.contact.sort(compareContact);\n parameter.contact.sort(compareContact);\n
// XXX sort\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n gadget.props.header_element.innerHTML = gadget.props.header_template({\n
left_url: result_list[0],\n
left_title: "Reset Password",\n
title: "Contact",\n title: "Contact",\n
right_url: result_list[0],\n right_url: result_list[1],\n
right_title: "New"\n right_title: "New"\n
});\n });\n
gadget.props.content_element.innerHTML =\n gadget.props.content_element.innerHTML =\n
...@@ -404,6 +413,25 @@ ...@@ -404,6 +413,25 @@
$(gadget.props.element).trigger("create");\n $(gadget.props.element).trigger("create");\n
});\n });\n
}\n }\n
\n
function renderErrorPage(gadget, error) {\n
var error_text = error;\n
return RSVP.Queue()\n
.push(function () {\n
return gadget.aq_pleasePublishMyState({page: PAGE_CONNECTION});\n
})\n
.push(function (connection_url) {\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
left_url: connection_url,\n
left_title: "Login",\n
title: "Error Message"\n
});\n
gadget.props.content_element.innerHTML = gadget.props.error_template({\n
error_message: error_text\n
});\n
$(gadget.props.element).trigger("create");\n
});\n
}\n
\n \n
function renderDialogPage(gadget, connection_gadget) {\n function renderDialogPage(gadget, connection_gadget) {\n
var jid,\n var jid,\n
...@@ -484,10 +512,8 @@ ...@@ -484,10 +512,8 @@
gadget.props.content_element.innerHTML =\n gadget.props.content_element.innerHTML =\n
gadget.props.login_template({});\n gadget.props.login_template({});\n
$(gadget.props.element).trigger("create");\n $(gadget.props.element).trigger("create");\n
gadget.props.content_element.querySelector("input[type=password]")\n gadget.props.content_element.querySelector("input[name=jid]")\n
.focus();\n .focus();\n
gadget.props.content_element.querySelector("input[type=password]")\n
.select();\n
return promiseEventListener(\n return promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.login-form\'),\n gadget.props.content_element.querySelector(\'form.login-form\'),\n
\'submit\',\n \'submit\',\n
...@@ -518,7 +544,16 @@ ...@@ -518,7 +544,16 @@
}\n }\n
\n \n
function renderNewContactPage(gadget, connection_gadget) {\n function renderNewContactPage(gadget, connection_gadget) {\n
var contact_url;\n
return new RSVP.Queue()\n
.push(function () {\n
return gadget.aq_pleasePublishMyState({page: PAGE_CONTACT});\n
})\n
.push(function (contact) {\n
contact_url = contact;\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n gadget.props.header_element.innerHTML = gadget.props.header_template({\n
left_url: contact_url,\n
left_title: "Back",\n
title: "New Contact"\n title: "New Contact"\n
});\n });\n
gadget.props.content_element.innerHTML =\n gadget.props.content_element.innerHTML =\n
...@@ -529,8 +564,6 @@ ...@@ -529,8 +564,6 @@
.focus();\n .focus();\n
gadget.props.content_element.querySelector("input[type=text]")\n gadget.props.content_element.querySelector("input[type=text]")\n
.select();\n .select();\n
return new RSVP.Queue()\n
.push(function () {\n
return promiseEventListener(\n return promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.new-contact-form\'),\n gadget.props.content_element.querySelector(\'form.new-contact-form\'),\n
\'submit\',\n \'submit\',\n
...@@ -548,6 +581,65 @@ ...@@ -548,6 +581,65 @@
return redirectToDefaultPage(gadget);\n return redirectToDefaultPage(gadget);\n
});\n });\n
}\n }\n
\n
function renderResetPasswordPage(gadget, connection_gadget, status) {\n
if(!status) {\n
status = "";\n
}\n
return new RSVP.Queue()\n
.push(function () {\n
return gadget.aq_pleasePublishMyState({page: PAGE_CONTACT});\n
})\n
.push(function (contact_url) {\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
left_url: contact_url,\n
left_title: "Back",\n
title: "Reset Password"\n
});\n
gadget.props.content_element.innerHTML =\n
gadget.props.reset_password_template({\n
message: status\n
});\n
$(gadget.props.element).trigger("create");\n
gadget.props.content_element.querySelector("input[type=submit]")\n
.disabled = false;\n
gadget.props.content_element.querySelector("input[name=new_passwd]")\n
.value = "";\n
gadget.props.content_element.querySelector("input[name=repeat_passwd]")\n
.value = "";\n
gadget.props.content_element.querySelector("input[name=new_passwd]")\n
.focus();\n
return promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.reset-password-form\'),\n
\'submit\',\n
false\n
);\n
})\n
.push(function (submit_event) {\n
var matched = false;\n
gadget.props.content_element.querySelector("input[type=submit]")\n
.disabled = true;\n
matched = validatePassword(\n
submit_event.target[1].value,\n
submit_event.target[2].value\n
);\n
if(matched) {\n
return connection_gadget.resetPassword(\n
submit_event.target[0].value,\n
submit_event.target[1].value\n
)\n
.push(function (status) {\n
return renderResetPasswordPage(gadget, connection_gadget, status);\n
}, function (error) {\n
var message = "Password Reset Failed.";\n
return renderResetPasswordPage(gadget, connection_gadget, message);\n
});\n
} else {\n
var message = "Password does not match.";\n
return renderResetPasswordPage(gadget, connection_gadget, message);\n
}\n
});\n
}\n
\n \n
rJS(window)\n rJS(window)\n
.ready(function (g) {\n .ready(function (g) {\n
...@@ -575,6 +667,12 @@ ...@@ -575,6 +667,12 @@
g.props.history_template = Handlebars.compile(\n g.props.history_template = Handlebars.compile(\n
document.querySelector(".history-template").innerHTML\n document.querySelector(".history-template").innerHTML\n
);\n );\n
g.props.error_template = Handlebars.compile(\n
document.querySelector(".error-template").innerHTML\n
);\n
g.props.reset_password_template = Handlebars.compile(\n
document.querySelector(".reset-password-template").innerHTML\n
);\n
g.props.message_template = Handlebars.compile(\n g.props.message_template = Handlebars.compile(\n
document.querySelector(".message-template").innerHTML\n document.querySelector(".message-template").innerHTML\n
);\n );\n
...@@ -596,6 +694,21 @@ ...@@ -596,6 +694,21 @@
return gadget.getDeclaredGadget(CONNECTION_GADGET_SCOPE)\n return gadget.getDeclaredGadget(CONNECTION_GADGET_SCOPE)\n
.push(function (connection_gadget) {\n .push(function (connection_gadget) {\n
return connection_gadget.sendPresence();\n return connection_gadget.sendPresence();\n
})\n
.push(function (){\n
return gadget.getDeclaredGadget(CONNECTION_GADGET_SCOPE);\n
})\n
.push(function (connection_gadget) {\n
return connection_gadget.fetchRoster();\n
})\n
.push(function(all_contacts){\n
var key;\n
for (key in all_contacts) {\n
initializeContact(gadget, all_contacts[key].jid);\n
}\n
}, function (error) {\n
var error_text = "Roster Fetching Failed";\n
return renderErrorPage(gadget, error_text);\n
});\n });\n
})\n })\n
.allowPublicAcquisition("notifyXMPPConnecting", function () {\n .allowPublicAcquisition("notifyXMPPConnecting", function () {\n
...@@ -673,6 +786,26 @@ ...@@ -673,6 +786,26 @@
argument_list[2], true);\n argument_list[2], true);\n
})\n })\n
\n \n
.allowPublicAcquisition("notifyXMPPConnectingFail", function () {\n
var gadget = this,\n
error_text = \'XMPPConnectingFail\';\n
return renderErrorPage(gadget, error_text);\n
})\n
.allowPublicAcquisition("notifyXMPPDisconnecting", function () {\n
var gadget = this,\n
error_text = \'XMPPDisconnecting\';\n
return renderErrorPage(gadget, error_text);\n
})\n
.allowPublicAcquisition("notifyXMPPDisconnected", function () {\n
var gadget = this,\n
error_text = \'XMPPDisconnected\';\n
return renderErrorPage(gadget, error_text);\n
})\n
.allowPublicAcquisition("notifyXMPPAuthenticatingFailed", function (error_data) {\n
var gadget = this,\n
error_text = \'XMPPAuthenticatingFailed\';\n
return renderErrorPage(gadget, error_text);\n
})\n
.declareService(function () {\n .declareService(function () {\n
\n \n
function dropNotification() {\n function dropNotification() {\n
...@@ -715,6 +848,8 @@ ...@@ -715,6 +848,8 @@
method = renderDialogPage;\n method = renderDialogPage;\n
} else if (options.page === PAGE_HISTORY) {\n } else if (options.page === PAGE_HISTORY) {\n
method = renderHistoryPage;\n method = renderHistoryPage;\n
} else if (options.page === PAGE_PASSWORD) {\n
method = renderResetPasswordPage;\n
} else {\n } else {\n
throw new Error("not implemented page " + options.page);\n throw new Error("not implemented page " + options.page);\n
}\n }\n
...@@ -863,7 +998,7 @@ ...@@ -863,7 +998,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>klaus.woelfel</string> </value> <value> <string>zope</string> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -877,7 +1012,7 @@ ...@@ -877,7 +1012,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>942.15804.3325.32187</string> </value> <value> <string>944.5545.36219.41881</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -895,8 +1030,8 @@ ...@@ -895,8 +1030,8 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1428663088.08</float> <float>1435744547.72</float>
<string>UTC</string> <string>GMT</string>
</tuple> </tuple>
</state> </state>
</object> </object>
......
...@@ -347,45 +347,69 @@ ...@@ -347,45 +347,69 @@
deferServerConnection(this);\n deferServerConnection(this);\n
})\n })\n
\n \n
// .declareMethod(\'fetchRoster\', function () {\n .declareMethod(\'fetchRoster\', function () {\n
// var defer = RSVP.defer();\n var defer = RSVP.defer();\n
// \n function jsonifyResponse(domElt) {\n
// function jsonifyResponse(domElt) {\n try {\n
// try {\n var result = [],\n
// var result = [],\n elt,\n
// elt,\n json_elt,\n
// json_elt,\n len,\n
// len,\n i,\n
// i,\n len2,\n
// len2,\n j,\n
// j,\n item_list = domElt.querySelectorAll("item");\n
// item_list = domElt.querySelectorAll("item");\n len = item_list.length;\n
// len = item_list.length;\n for (i = 0; i < len; i += 1) {\n
// for (i = 0; i < len; i += 1) {\n elt = item_list[i];\n
// elt = item_list[i];\n len2 = elt.attributes.length;\n
// len2 = elt.attributes.length;\n json_elt = {};\n
// json_elt = {};\n for (j = 0; j < len2; j += 1) {\n
// for (j = 0; j < len2; j += 1) {\n json_elt[elt.attributes[j].name] = elt.attributes[j].value;\n
// json_elt[elt.attributes[j].name] = elt.attributes[j].value;\n }\n
// }\n result.push(json_elt);\n
// result.push(json_elt);\n }\n
// }\n defer.resolve(result);\n
// defer.resolve(result);\n } catch (error) {\n
// } catch (error) {\n defer.reject(error);\n
// defer.reject(error);\n }\n
// }\n }\n
// }\n this.props.connection.sendIQ(\n
// \n $iq({type: "get"}).c("query", {xmlns: Strophe.NS.ROSTER}),\n
// this.props.connection.sendIQ(\n jsonifyResponse,\n
// $iq({type: "get"}).c("query", {xmlns: Strophe.NS.ROSTER}),\n defer.reject\n
// jsonifyResponse,\n );\n
// defer.reject\n return defer.promise;\n
// );\n })\n
// \n
// return defer.promise;\n
// \n
// })\n
\n \n
.declareMethod(\'resetPassword\', function (server, new_passwd) {\n
var defer = RSVP.defer();\n
function jsonifyResponse(domElt) {\n
try {\n
var result = [],\n
type = domElt.getAttribute(\'type\');\n
if(type === "result") {\n
result.push("Password Reset Success.");\n
}\n
else {\n
throw new Error("Password Reset Failure.");\n
}\n
defer.resolve(result);\n
} catch (error) {\n
defer.reject(error);\n
}\n
}\n
var uid = this.props.jid.split(\'@\')[0];\n
this.props.connection.sendIQ(\n
$iq({to: server, type: "set"})\n
.c("query", {xmlns: "jabber:iq:register"})\n
.c("username").t(uid).up()\n
.c("password").t(new_passwd).up(),\n
jsonifyResponse,\n
defer.reject\n
);\n
return defer.promise;\n
})\n
.declareMethod(\'sendPresence\', function () {\n .declareMethod(\'sendPresence\', function () {\n
this.props.connection.send(\n this.props.connection.send(\n
$pres().tree()\n $pres().tree()\n
...@@ -545,7 +569,7 @@ ...@@ -545,7 +569,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>romain</string> </value> <value> <string>zope</string> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -559,7 +583,7 @@ ...@@ -559,7 +583,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>939.33961.3512.52974</string> </value> <value> <string>944.5651.30805.18688</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -577,7 +601,7 @@ ...@@ -577,7 +601,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1418214516.59</float> <float>1435744650.8</float>
<string>GMT</string> <string>GMT</string>
</tuple> </tuple>
</state> </state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment