Commit 0363c0e8 authored by Vivek's avatar Vivek Committed by Kazuhiko Shiozaki

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

parent 88786a70
......@@ -135,8 +135,9 @@
<ul data-role="listview" data-inset="true">\n
{{#each contact}}\n
<li>\n
{{#if status}}\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
<span class="ui-li-count">!</span>\n
{{/if}}\n
......@@ -144,6 +145,17 @@
{{else}}\n
{{jid}}\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
{{/each}}\n
</ul>\n
......@@ -207,10 +219,37 @@
</div>\n
</script>\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
\n
<script class="history-template" type="text/x-handlebars-template"><pre style="white-space: pre-wrap;">{{text}}</pre></script>\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
{{#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
......@@ -368,7 +407,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>klaus.woelfel</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -382,7 +421,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>942.15924.54448.8823</string> </value>
<value> <string>944.5553.6477.32460</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -400,8 +439,8 @@
</tuple>
<state>
<tuple>
<float>1428669417.76</float>
<string>UTC</string>
<float>1435739472.1</float>
<string>GMT</string>
</tuple>
</state>
</object>
......
......@@ -124,6 +124,7 @@
PAGE_DIALOG = "dialog",\n
PAGE_HISTORY = "history",\n
PAGE_NEW_CONTACT = "subscribe",\n
PAGE_PASSWORD = "password",\n
DEFAULT_PAGE = PAGE_CONTACT,\n
CONNECTION_GADGET_URL = "./gadget_jabberconnection.html",\n
CONNECTION_GADGET_SCOPE = "connection",\n
......@@ -139,6 +140,10 @@
result = -1;\n
} else if (b.new_message && (!a.new_message)) {\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
result = 1;\n
} else if (a.jid < b.jid) {\n
......@@ -149,6 +154,13 @@
return result;\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
if (!(gadget.props.contact_dict.hasOwnProperty(jid))) {\n
gadget.props.contact_dict[jid] = {\n
......@@ -296,39 +308,36 @@
return RSVP.Queue()\n
.push(function () {\n
var promise_list = [\n
gadget.aq_pleasePublishMyState({page: PAGE_PASSWORD}),\n
gadget.aq_pleasePublishMyState({page: PAGE_NEW_CONTACT})\n
],\n
key;\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
gadget.aq_pleasePublishMyState({page: PAGE_DIALOG, jid: key})\n
);\n
}\n
}\n
return RSVP.all(promise_list);\n
})\n
.push(function (result_list) {\n
var i = 1,\n
var i = 2,\n
parameter = {contact: []},\n
key2;\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
jid: key2,\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
i += 1;\n
}\n
}\n
parameter.contact.sort(compareContact);\n
// XXX sort\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
right_url: result_list[0],\n
right_url: result_list[1],\n
right_title: "New"\n
});\n
gadget.props.content_element.innerHTML =\n
......@@ -404,6 +413,25 @@
$(gadget.props.element).trigger("create");\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
function renderDialogPage(gadget, connection_gadget) {\n
var jid,\n
......@@ -484,10 +512,8 @@
gadget.props.content_element.innerHTML =\n
gadget.props.login_template({});\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
gadget.props.content_element.querySelector("input[type=password]")\n
.select();\n
return promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.login-form\'),\n
\'submit\',\n
......@@ -518,7 +544,16 @@
}\n
\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
left_url: contact_url,\n
left_title: "Back",\n
title: "New Contact"\n
});\n
gadget.props.content_element.innerHTML =\n
......@@ -529,8 +564,6 @@
.focus();\n
gadget.props.content_element.querySelector("input[type=text]")\n
.select();\n
return new RSVP.Queue()\n
.push(function () {\n
return promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.new-contact-form\'),\n
\'submit\',\n
......@@ -548,6 +581,65 @@
return redirectToDefaultPage(gadget);\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
rJS(window)\n
.ready(function (g) {\n
......@@ -575,6 +667,12 @@
g.props.history_template = Handlebars.compile(\n
document.querySelector(".history-template").innerHTML\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
document.querySelector(".message-template").innerHTML\n
);\n
......@@ -596,6 +694,21 @@
return gadget.getDeclaredGadget(CONNECTION_GADGET_SCOPE)\n
.push(function (connection_gadget) {\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
.allowPublicAcquisition("notifyXMPPConnecting", function () {\n
......@@ -673,6 +786,26 @@
argument_list[2], true);\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
\n
function dropNotification() {\n
......@@ -715,6 +848,8 @@
method = renderDialogPage;\n
} else if (options.page === PAGE_HISTORY) {\n
method = renderHistoryPage;\n
} else if (options.page === PAGE_PASSWORD) {\n
method = renderResetPasswordPage;\n
} else {\n
throw new Error("not implemented page " + options.page);\n
}\n
......@@ -863,7 +998,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>klaus.woelfel</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -877,7 +1012,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>942.15804.3325.32187</string> </value>
<value> <string>944.5545.36219.41881</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -895,8 +1030,8 @@
</tuple>
<state>
<tuple>
<float>1428663088.08</float>
<string>UTC</string>
<float>1435744547.72</float>
<string>GMT</string>
</tuple>
</state>
</object>
......
......@@ -347,45 +347,69 @@
deferServerConnection(this);\n
})\n
\n
// .declareMethod(\'fetchRoster\', function () {\n
// var defer = RSVP.defer();\n
// \n
// function jsonifyResponse(domElt) {\n
// try {\n
// var result = [],\n
// elt,\n
// json_elt,\n
// len,\n
// i,\n
// len2,\n
// j,\n
// item_list = domElt.querySelectorAll("item");\n
// len = item_list.length;\n
// for (i = 0; i < len; i += 1) {\n
// elt = item_list[i];\n
// len2 = elt.attributes.length;\n
// json_elt = {};\n
// for (j = 0; j < len2; j += 1) {\n
// json_elt[elt.attributes[j].name] = elt.attributes[j].value;\n
// }\n
// result.push(json_elt);\n
// }\n
// defer.resolve(result);\n
// } catch (error) {\n
// defer.reject(error);\n
// }\n
// }\n
// \n
// this.props.connection.sendIQ(\n
// $iq({type: "get"}).c("query", {xmlns: Strophe.NS.ROSTER}),\n
// jsonifyResponse,\n
// defer.reject\n
// );\n
// \n
// return defer.promise;\n
// \n
// })\n
.declareMethod(\'fetchRoster\', function () {\n
var defer = RSVP.defer();\n
function jsonifyResponse(domElt) {\n
try {\n
var result = [],\n
elt,\n
json_elt,\n
len,\n
i,\n
len2,\n
j,\n
item_list = domElt.querySelectorAll("item");\n
len = item_list.length;\n
for (i = 0; i < len; i += 1) {\n
elt = item_list[i];\n
len2 = elt.attributes.length;\n
json_elt = {};\n
for (j = 0; j < len2; j += 1) {\n
json_elt[elt.attributes[j].name] = elt.attributes[j].value;\n
}\n
result.push(json_elt);\n
}\n
defer.resolve(result);\n
} catch (error) {\n
defer.reject(error);\n
}\n
}\n
this.props.connection.sendIQ(\n
$iq({type: "get"}).c("query", {xmlns: Strophe.NS.ROSTER}),\n
jsonifyResponse,\n
defer.reject\n
);\n
return defer.promise;\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
this.props.connection.send(\n
$pres().tree()\n
......@@ -545,7 +569,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>romain</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -559,7 +583,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>939.33961.3512.52974</string> </value>
<value> <string>944.5651.30805.18688</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -577,7 +601,7 @@
</tuple>
<state>
<tuple>
<float>1418214516.59</float>
<float>1435744650.8</float>
<string>GMT</string>
</tuple>
</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