Commit d161f838 authored by Georgios Dagkakis's avatar Georgios Dagkakis Committed by Cédric Le Ninivin

Jabber multiline

erp5_web_jabber_client: Allow user to send multi-line messages

User can change between single-line and multi-line mode
using one button.

/reviewed-on nexedi/erp5!114
parents a08a3c33 b8af2f09
...@@ -12,13 +12,24 @@ ...@@ -12,13 +12,24 @@
<!-- custom script --> <!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script> <script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_jabberclient_page_dialog.js" type="text/javascript"></script> <script src="gadget_jabberclient_page_dialog.js" type="text/javascript"></script>
<script id="input-template" type="text/x-handlebars-template">
<input class="input-content" type="text" data-enhanced="true" name="content"
placeholder="Write something..." value="" required>
</script>
<script id="textarea-template" type="text/x-handlebars-template">
<textarea class="textarea-content" type="text" data-enhanced="true" name="content"
placeholder="Write a multi-line message..." value="" required></textarea>
</script>
</head> </head>
<body> <body>
<div class="discussion-content"></div> <div class="discussion-content"></div>
<div data-role="footer" data-position="fixed" data-tap-toggle="false"> <div data-role="footer" data-position="fixed" data-tap-toggle="false">
<form class="message-form"> <form class="message-form">
<div class="ui-input-text ui-corner-all ui-body-inherit ui-shadow-inset ui-input-has-clear"> <div class="ui-input-text ui-corner-all ui-body-inherit ui-shadow-inset ui-input-has-clear ui-input-has-multiline">
<input type="text" data-enhanced="true" name="content" placeholder="Write something..." value="" required> <div class="custom-mode-change ui-btn ui-btn-icon-notext ui-input-clear ui-input-btn ui-corner-all ui-icon-comment ui-btn-left">
<input data-enhanced="true" type="button" value="">
</div>
<div class="ui-btn ui-input-clear ui-input-btn ui-corner-all ui-icon-edit ui-btn-icon-notext"> <div class="ui-btn ui-input-clear ui-input-btn ui-corner-all ui-icon-edit ui-btn-icon-notext">
<input data-enhanced="true" type="submit" value="Send"> <input data-enhanced="true" type="submit" value="Send">
</div> </div>
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>949.30780.1199.42069</string> </value> <value> <string>950.63332.2255.41369</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1456843290.96</float> <float>1462370312.21</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*global window, document, rJS, RSVP, loopEventListener*/ /*global window, document, rJS, RSVP, Handlebars, loopEventListener*/
/*jslint nomen: true, indent: 2, maxerr: 3 */ /*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, document, rJS, RSVP, loopEventListener) { (function (window, document, rJS, RSVP, Handlebars, loopEventListener) {
"use strict"; "use strict";
function scroll() { function scroll() {
...@@ -13,10 +13,29 @@ ...@@ -13,10 +13,29 @@
}); });
} }
function getDomFromString(str) {
var temp_div = document.createElement('div');
temp_div.innerHTML = str.trim();
return temp_div.firstChild;
}
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
input_source = gadget_klass.__template_element
.getElementById("input-template")
.innerHTML,
input_template = Handlebars.compile(input_source),
textarea_source = gadget_klass.__template_element
.getElementById("textarea-template")
.innerHTML,
textarea_template = Handlebars.compile(textarea_source),
// MESSAGE_FRESHNESS 30 minutes // MESSAGE_FRESHNESS 30 minutes
var MESSAGE_FRESHNESS = 1800000; MESSAGE_FRESHNESS = 1800000;
rJS(window) gadget_klass
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// ready // ready
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -30,6 +49,10 @@ ...@@ -30,6 +49,10 @@
return g.getElement() return g.getElement()
.push(function (element) { .push(function (element) {
g.props.element = element; g.props.element = element;
g.props.template_container = element.querySelector('.ui-input-has-multiline');
g.props.keep_text_dict = {'oneline': '', 'textarea': ''};
g.props.template_container.insertBefore(getDomFromString(input_template()),
g.props.template_container.firstChild);
}); });
}) })
...@@ -48,9 +71,12 @@ ...@@ -48,9 +71,12 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) { .declareMethod("render", function (options) {
var gadget = this, var gadget = this,
ul = document.createElement("ul"); ul = document.createElement("ul"),
template_container = gadget.props.template_container;
ul.setAttribute("data-role", "listview"); ul.setAttribute("data-role", "listview");
gadget.props.jid = options.jid; gadget.props.jid = options.jid;
template_container.children[0].focus();
template_container.children[0].select();
return gadget.updateHeader({ return gadget.updateHeader({
page_title: options.jid page_title: options.jid
}) })
...@@ -108,14 +134,20 @@ ...@@ -108,14 +134,20 @@
index = line.indexOf('] '); index = line.indexOf('] ');
if (index !== -1) { if (index !== -1) {
// Check message freshness // Check message freshness
// If we receive one multiline message, then the lines after the first
// would not start with the date. So this would return Invalid Date
message_date = new Date(line.substring(1, index)); message_date = new Date(line.substring(1, index));
// Check direction and cut the date from the start of the line.
// This should be done only if it is a unique line or the first
// line of a multi-line message. Other lines will retain direction
// of the first
if (isNaN(message_date) === false) {
if (previous_message_date === undefined) { if (previous_message_date === undefined) {
previous_message_date = new Date(message_date - MESSAGE_FRESHNESS - 2); previous_message_date = new Date(message_date - MESSAGE_FRESHNESS - 2);
} }
if (message_date - previous_message_date > MESSAGE_FRESHNESS) { if (message_date - previous_message_date > MESSAGE_FRESHNESS) {
is_old = true; is_old = true;
} }
// Check direction
tmp_line = line.substring(index + 2); tmp_line = line.substring(index + 2);
if (tmp_line.indexOf('> ') === 0) { if (tmp_line.indexOf('> ') === 0) {
message_is_incoming = false; message_is_incoming = false;
...@@ -123,6 +155,7 @@ ...@@ -123,6 +155,7 @@
message_is_incoming = true; message_is_incoming = true;
} }
line = tmp_line.substring(2); line = tmp_line.substring(2);
}
if (message_is_incoming !== is_incoming || is_old) { if (message_is_incoming !== is_incoming || is_old) {
appendText(displayed_text, is_incoming); appendText(displayed_text, is_incoming);
is_incoming = message_is_incoming; is_incoming = message_is_incoming;
...@@ -149,13 +182,21 @@ ...@@ -149,13 +182,21 @@
}) })
.declareService(function () { .declareService(function () {
var form_gadget = this; var form_gadget = this,
template_container = form_gadget.props.template_container,
keep_text_dict = form_gadget.props.keep_text_dict;
function formSubmit(submit_event) { function formSubmit(submit_event) {
return form_gadget.notifySubmitting() return form_gadget.notifySubmitting()
.push(function () { .push(function () {
var text = submit_event.target[0].value; var text = submit_event.target[0].value;
submit_event.target[0].value = ""; submit_event.target[0].value = "";
keep_text_dict.oneline = "";
keep_text_dict.textarea = "";
template_container.removeChild(template_container.firstChild);
template_container.insertBefore(getDomFromString(input_template()),
template_container.firstChild);
template_container.children[0].focus();
template_container.children[0].select();
return form_gadget.jio_putAttachment( return form_gadget.jio_putAttachment(
form_gadget.props.jid, form_gadget.props.jid,
'MESSAGE', 'MESSAGE',
...@@ -185,8 +226,41 @@ ...@@ -185,8 +226,41 @@
); );
}) })
.declareService(function () {
var gadget = this,
template_container = gadget.props.template_container,
keep_text_dict = gadget.props.keep_text_dict;
function changeMode() {
if (template_container.children[0].className === 'input-content') {
keep_text_dict.oneline = template_container.children[0].value;
template_container.removeChild(template_container.firstChild);
template_container.insertBefore(getDomFromString(textarea_template()),
template_container.firstChild);
template_container.children[0].value = keep_text_dict.textarea;
} else {
keep_text_dict.textarea = template_container.children[0].value;
template_container.removeChild(template_container.firstChild);
template_container.insertBefore(getDomFromString(input_template()),
template_container.firstChild);
template_container.children[0].value = keep_text_dict.oneline;
}
var typing_field = template_container.children[0];
typing_field.focus();
typing_field.select();
typing_field.selectionStart = typing_field.selectionEnd = typing_field.value.length;
}
// Listen to button click
return loopEventListener(
gadget.props.element.querySelector('.custom-mode-change'),
'click',
false,
changeMode
);
})
.declareService(function () { .declareService(function () {
scroll(); scroll();
}); });
}(window, document, rJS, RSVP, loopEventListener)); }(window, document, rJS, RSVP, Handlebars, loopEventListener));
\ No newline at end of file \ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>949.36447.38496.63744</string> </value> <value> <string>950.63396.22857.42769</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1456908330.96</float> <float>1462370315.51</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -1371,6 +1371,13 @@ html .ui-table-header:before { ...@@ -1371,6 +1371,13 @@ html .ui-table-header:before {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
} }
/* multiline */
.ui-input-has-multiline {
padding-left: 2.375em;
}
.ui-input-has-multiline textarea {
width: 100%;
}
/* correctly display loader TODO: REMOVE */ /* correctly display loader TODO: REMOVE */
html body .ui-input-has-clear .ui-icon-spinner:after { html body .ui-input-has-clear .ui-icon-spinner:after {
font-size: 1.5em; font-size: 1.5em;
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>949.22640.50771.7816</string> </value> <value> <string>951.6248.60986.31163</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1456317267.11</float> <float>1462873727.38</float>
<string>UTC</string> <string>UTC</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