Commit c6f0223a authored by Romain Courteaud's avatar Romain Courteaud

romain_dev: forum improve post rendering

parent cf20c2e2
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
<!-- renderjs --> <!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script> <script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script> <script src="renderjs.js" type="text/javascript"></script>
<!--link rel="stylesheet" href="gadget_erp5_page_nx_project_quality.css"-->
<!-- custom script --> <!-- custom script -->
<script src="jiodev.js" type="text/javascript"></script> <script src="jiodev.js" type="text/javascript"></script>
......
...@@ -238,7 +238,7 @@ ...@@ -238,7 +238,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>989.1604.35674.62737</string> </value> <value> <string>989.21729.29819.50124</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -256,7 +256,7 @@ ...@@ -256,7 +256,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1609424915.53</float> <float>1610632417.11</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
// XXX create topic by followup (allDocs group by follow up) // XXX create topic by followup (allDocs group by follow up)
var DISPLAY_READER = 'display_reader', var DISPLAY_READER = 'display_reader',
DISPLAY_THREAD = 'display_thread',
DISPLAY_POST = 'display_post',
MAIN_SCOPE = 'child_scope'; MAIN_SCOPE = 'child_scope';
function loadChildGadget(gadget, gadget_url, must_declare, callback) { function loadChildGadget(gadget, gadget_url, must_declare, callback) {
...@@ -117,7 +119,7 @@ ...@@ -117,7 +119,7 @@
} }
function renderDiscussionThread(gadget, must_declare, jio_key) { function renderDiscussionThread(gadget, must_declare, jio_key) {
return loadChildGadget(gadget, "gadget_erp5_pt_form_dialog.html", return loadChildGadget(gadget, "gadget_erp5_pt_form_view_editable.html",
must_declare, function (form_gadget) { must_declare, function (form_gadget) {
var thread_info_dict; var thread_info_dict;
...@@ -209,7 +211,7 @@ ...@@ -209,7 +211,7 @@
"hidden": 0 "hidden": 0
}; };
group_list.push([ group_list.push([
"center", "bottom",
[["nutnut"]] [["nutnut"]]
], [ ], [
"hidden", ["listbox_modification_date"] "hidden", ["listbox_modification_date"]
...@@ -496,6 +498,10 @@ ...@@ -496,6 +498,10 @@
.allowPublicAcquisition("jio_allDocs", function (param_list, scope) { .allowPublicAcquisition("jio_allDocs", function (param_list, scope) {
// XXX Convert iso date to a DateTime field // XXX Convert iso date to a DateTime field
// XXX Paginate message to last message on modification date column // XXX Paginate message to last message on modification date column
if (this.state.display_step !== DISPLAY_READER) {
throw new rJS.AcquisitionError();
}
var gadget = this, var gadget = this,
options = param_list[0]; options = param_list[0];
console.log(scope, param_list); console.log(scope, param_list);
...@@ -560,16 +566,26 @@ ...@@ -560,16 +566,26 @@
}); });
}) })
.setState({
display_step: DISPLAY_READER
})
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
console.log(options); console.log(options);
var display_step,
jio_key = options.jio_key;
if (jio_key === undefined) {
display_step = DISPLAY_READER;
} else if ((jio_key.match(/\//g) || []).length === 1) {
// XXX HACK
display_step = DISPLAY_THREAD;
}
return this.changeState({ return this.changeState({
first_render: true, // first_render: true,
page: options.page, page: options.page,
jio_key: options.jio_key, jio_key: jio_key,
options: options display_step: display_step,
options: options,
// Force display in any case
render_timestamp: new Date().getTime()
/* /*
display_step: DISPLAY_TREE, display_step: DISPLAY_TREE,
// Only build the bt5 during the first query // Only build the bt5 during the first query
...@@ -596,51 +612,28 @@ ...@@ -596,51 +612,28 @@
console.log('changestate', modification_dict); console.log('changestate', modification_dict);
var gadget = this; var gadget = this;
// Always refresh the reader
if (gadget.state.display_step === DISPLAY_READER) { if (gadget.state.display_step === DISPLAY_READER) {
if (gadget.state.jio_key === undefined) { return renderDiscussionThreadList(
return renderDiscussionThreadList( gadget,
gadget, modification_dict.hasOwnProperty('display_step')
modification_dict.hasOwnProperty('display_step') || modification_dict.first_render );
); }
} if (gadget.state.display_step === DISPLAY_THREAD) {
// XXX HACK return renderDiscussionThread(
if ((gadget.state.jio_key.match(/\//g) || []).length === 1) { gadget,
return renderDiscussionThread( modification_dict.hasOwnProperty('display_step'),
gadget, gadget.state.jio_key
modification_dict.hasOwnProperty('display_step') || modification_dict.first_render, );
gadget.state.jio_key }
); /*
}
return renderDiscussionPost( return renderDiscussionPost(
gadget, gadget,
modification_dict.hasOwnProperty('display_step') || modification_dict.first_render, modification_dict.hasOwnProperty('display_step') || modification_dict.first_render,
gadget.state.jio_key gadget.state.jio_key
); );
} }
/*
if (gadget.state.display_step === DISPLAY_TREE) {
console.log(modification_dict);
if (modification_dict.hasOwnProperty('display_step')) {
return renderTreeView(gadget,
modification_dict.hasOwnProperty('extract'));
}
if (modification_dict.hasOwnProperty('expand_tree')) {
return expandTreeView(gadget);
}
}
if (modification_dict.display_step === DISPLAY_DIFF) {
return renderDiffView(gadget);
}
if (modification_dict.display_step === DISPLAY_CHANGELOG) {
return renderChangelogView(gadget);
}
*/ */
if (modification_dict.hasOwnProperty('display_step')) { throw new Error('Unhandled display step: ' + gadget.state.display_step);
throw new Error('Unhandled display step: ' + gadget.state.display_step);
}
}); });
}(window, rJS, RSVP, domsugar, SimpleQuery, ComplexQuery, Query)); }(window, rJS, RSVP, domsugar, SimpleQuery, ComplexQuery, Query));
\ No newline at end of file
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>989.18879.37912.30737</string> </value> <value> <string>989.21570.59351.45277</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -258,7 +258,7 @@ ...@@ -258,7 +258,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1610461438.43</float> <float>1610622907.09</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
div[data-gadget-url$="gadget_thread_reader.html"] > ol {
max-width: 50em;
}
div[data-gadget-url$="gadget_thread_reader.html"] > ol > li {
padding-bottom: 2em;
}
div[data-gadget-url$="gadget_thread_reader.html"] > ol > li:nth-child(even) {
background-color: rgba(230, 230, 230, 0.65);
}
div[data-gadget-url$="gadget_thread_reader.html"] > ol > li > div.post_content {
display: inline-block;
}
div[data-gadget-url$="gadget_thread_reader.html"] > ol > li > div.post_content > div {
margin-top: 1em;
}
div[data-gadget-url$="gadget_thread_reader.html"] > ol > li > div.post_avatar {
display: inline-block;
margin-right: 1em;
width: 3em;
height: 3em;
line-height: 3em;
text-align: center;
border-radius: 50%;
background: #0E81C2;
color: #FFFFFF;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
vertical-align: top;
text-transform: uppercase;
}
div[data-gadget-url$="gadget_thread_reader.html"] > ol > li + li {
padding-top: 1em;
}
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
<title>Thread Reader</title> <title>Thread Reader</title>
<!-- renderjs --> <!-- renderjs -->
<link rel="stylesheet" href="gadget_thread_reader.css">
<script src="rsvp.js" type="text/javascript"></script> <script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script> <script src="renderjs.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script> <script src="domsugar.js" type="text/javascript"></script>
......
...@@ -238,7 +238,7 @@ ...@@ -238,7 +238,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>989.18650.40702.358</string> </value> <value> <string>989.21729.52523.14404</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -256,7 +256,7 @@ ...@@ -256,7 +256,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1610447694.2</float> <float>1610632439.05</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -7,6 +7,37 @@ ...@@ -7,6 +7,37 @@
loading_class_list = ['ui-icon-spinner', 'ui-btn-icon-left'], loading_class_list = ['ui-icon-spinner', 'ui-btn-icon-left'],
disabled_class = 'ui-disabled'; disabled_class = 'ui-disabled';
function getRelativeTimeString(current_date, date) {
var diff,
abs,
second = 1000,
minute = second * 60,
hour = minute * 60,
day = hour * 24,
week = day * 7,
time_format = new Intl.RelativeTimeFormat();
diff = date.getFullYear() - current_date.getFullYear();
if (diff !== 0) {
return time_format.format(diff, 'year');
}
diff = date - current_date;
abs = Math.abs(diff);
// "year", "quarter", "month", "week", "day", "hour", "minute", "second"
console.log(current_date, date, abs, week, day);
if (abs > (week * 2)) {
return time_format.format(Math.floor(diff / week), 'week');
} else if (abs > (day * 2)) {
return time_format.format(Math.floor(diff / day), 'day');
} else if (abs > (hour * 2)) {
return time_format.format(Math.floor(diff / hour), 'hour');
} else {
return time_format.format(Math.floor(diff / minute), 'minute');
}
return date;
}
function buildFieldGadgetParam(value) { function buildFieldGadgetParam(value) {
var field_gadget_param; var field_gadget_param;
...@@ -386,13 +417,38 @@ ...@@ -386,13 +417,38 @@
}) })
)) ))
.push(function (viewer_list) { .push(function (viewer_list) {
var now = new Date();
domsugar(gadget.element, [ domsugar(gadget.element, [
domsugar('p', {text: 'Comments:'}),
domsugar('ol', allDocs_result.data.rows.map(function (entry, i) { domsugar('ol', allDocs_result.data.rows.map(function (entry, i) {
console.log(entry); var source_title = entry.value.source_title || '',
word_list = source_title.split(' '),
source_short_title;
if (word_list.length === 1) {
source_short_title = (word_list[0][0] || '?') + (word_list[0][1] || '');
} else {
source_short_title = word_list[0][0] + word_list[1][0];
}
return domsugar('li', [ return domsugar('li', [
viewer_list[i].element, domsugar('div', {
domsugar('hr') class: 'post_avatar',
text: source_short_title
}),
domsugar('div', {
class: 'post_content',
}, [
domsugar('strong', {text: source_title}),
" ",
domsugar('time', {
datetime: entry.value.modification_date,
title: entry.value.modification_date,
text: getRelativeTimeString(
now, new Date(entry.value.modification_date)
)
}),
domsugar('br'),
viewer_list[i].element,
// domsugar('hr')
])
]); ]);
})) }))
]); ]);
...@@ -768,6 +824,19 @@ ...@@ -768,6 +824,19 @@
return result_queue; return result_queue;
}) })
.onLoop(function () {
// update relative time
var now = new Date();
this.element.querySelectorAll("div.post_content > time").forEach(
function (element) {
element.textContent = getRelativeTimeString(
now, new Date(element.getAttribute('datetime'))
);
}
);
// Loop every minute
}, 1000 * 60)
////////////////////////////////////////////// //////////////////////////////////////////////
// render the listbox in an asynchronous way // render the listbox in an asynchronous way
////////////////////////////////////////////// //////////////////////////////////////////////
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>989.20325.997.53486</string> </value> <value> <string>989.21883.22115.61832</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -258,7 +258,7 @@ ...@@ -258,7 +258,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1610548223.31</float> <float>1610641779.85</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
@colorheaderbackground: #085078;
@colorsubheaderbackground: #0E81C2;
@foreground-text-shadow: 0 1px 2px rgba(0, 0, 0, 0.20);
@white: #FFFFFF;
@avatar_size: 3em;
div[data-gadget-url$="gadget_thread_reader.html"] {
& > ol {
// Limit the width to make reading more pleasant on large screen
max-width: 50em;
& > li {
padding-bottom: 2em;
&:nth-child(even) {
background-color: rgba(230, 230, 230, 0.65);
}
& > div.post_content {
display: inline-block;
& > div {
// Separate post info (user and time) from content
margin-top: 1em;
}
}
& > div.post_avatar {
display: inline-block;
margin-right: 1em;
width: @avatar_size;
height: @avatar_size;
line-height: @avatar_size;
text-align: center;
border-radius: 50%;
background: @colorsubheaderbackground;
color: @white;
text-shadow: @foreground-text-shadow;
vertical-align: top;
text-transform: uppercase;
}
& + li {
// Separate posts
// border-top: solid 1px @colorsubheaderbackground;
padding-top: 1em;
}
}
}
}
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>gadget_thread_reader.less</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/plain</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
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