Skip to content

Commit ca91601

Browse files
authored
Merge pull request #1005 from pkvach/feat/add-sorting-for-comments
Add sorting option for comments
2 parents 4694f21 + 00fc383 commit ca91601

10 files changed

Lines changed: 229 additions & 54 deletions

File tree

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ New Features
1212
- Add search for comments by URL in the admin interface (`#1000`_, pkvach)
1313
- Add CSS variables for better organization and flexibility (`#1001`_, pkvach)
1414
- Add support for comment search by Thread URL in admin interface (`#1020`_, pkvach)
15+
- Add sorting option for comments (`#1005`_, pkvach)
1516

1617
.. _#966: https://github.com/posativ/isso/pull/966
1718
.. _#998: https://github.com/isso-comments/isso/pull/998
1819
.. _#1000: https://github.com/isso-comments/isso/pull/1000
1920
.. _#1001: https://github.com/isso-comments/isso/pull/1001
2021
.. _#1020: https://github.com/isso-comments/isso/pull/1020
22+
.. _#1005: https://github.com/isso-comments/isso/pull/1005
2123

2224
Breaking Changes
2325
^^^^^^^^^^^^^^^^

docs/docs/reference/client-config.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ preferably in the script tag which embeds the JS:
1313
data-isso-max-comments-top="10"
1414
data-isso-max-comments-nested="5"
1515
data-isso-reveal-on-click="5"
16+
data-isso-sorting="newest"
1617
data-isso-avatar="true"
1718
data-isso-avatar-bg="#f0f0f0"
1819
data-isso-avatar-fg="#9abf88 #5698c4 #e279a3 #9163b6 ..."
@@ -255,6 +256,21 @@ data-isso-reply-notifications-default-enabled
255256
.. versionadded:: 0.13
256257

257258

259+
.. _data-isso-sorting:
260+
261+
data-isso-sorting
262+
Sort thread comments by specified sorting method.
263+
264+
Possible sorting methods:
265+
266+
- ``newest``: Bring newest comments to the top
267+
- ``oldest``: Bring oldest comments to the top
268+
- ``upvotes``: Bring most liked comments to the top
269+
270+
Default sorting is ``oldest``.
271+
272+
.. versionadded:: 0.13.1
273+
258274
Deprecated Client Settings
259275
--------------------------
260276

isso/db/comments.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,11 @@ def fetchall(self, mode=5, after=0, parent='any', order_by='id',
238238
yield dict(zip(fields_comments + fields_threads, item))
239239

240240
def fetch(self, uri, mode=5, after=0, parent='any',
241-
order_by='id', asc=1, limit=None):
241+
order_by='id', asc=1, limit=None, offset=0):
242242
"""
243243
Return comments for :param:`uri` with :param:`mode`.
244244
"""
245-
sql = ['SELECT comments.* FROM comments INNER JOIN threads ON',
245+
sql = ['SELECT comments.*, likes - dislikes AS karma FROM comments INNER JOIN threads ON',
246246
' threads.uri=? AND comments.tid=threads.id AND (? | comments.mode) = ?',
247247
' AND comments.created>?']
248248

@@ -256,14 +256,18 @@ def fetch(self, uri, mode=5, after=0, parent='any',
256256
sql_args.append(parent)
257257

258258
# custom sanitization
259-
if order_by not in ['id', 'created', 'modified', 'likes', 'dislikes']:
259+
if order_by not in ['id', 'created', 'modified', 'likes', 'dislikes', 'karma']:
260260
order_by = 'id'
261261
sql.append('ORDER BY ')
262262
sql.append(order_by)
263263
if not asc:
264264
sql.append(' DESC')
265265

266-
if limit:
266+
if offset and limit:
267+
sql.append('LIMIT ?,?')
268+
sql_args.append(offset)
269+
sql_args.append(limit)
270+
elif limit:
267271
sql.append('LIMIT ?')
268272
sql_args.append(limit)
269273

@@ -350,19 +354,18 @@ def vote(self, upvote, id, remote_addr):
350354
return {'likes': likes + 1, 'dislikes': dislikes}
351355
return {'likes': likes, 'dislikes': dislikes + 1}
352356

353-
def reply_count(self, url, mode=5, after=0):
357+
def reply_count(self, url, mode=5):
354358
"""
355359
Return comment count for main thread and all reply threads for one url.
356360
"""
357361

358362
sql = ['SELECT comments.parent,count(*)',
359363
'FROM comments INNER JOIN threads ON',
360364
' threads.uri=? AND comments.tid=threads.id AND',
361-
' (? | comments.mode = ?) AND',
362-
' comments.created > ?',
365+
' (? | comments.mode = ?)',
363366
'GROUP BY comments.parent']
364367

365-
return dict(self.db.execute(sql, [url, mode, mode, after]).fetchall())
368+
return dict(self.db.execute(sql, [url, mode, mode]).fetchall())
366369

367370
def count(self, *urls):
368371
"""

isso/js/app/api.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,13 @@ var view = function(id, plain) {
138138
return deferred.promise;
139139
};
140140

141-
var fetch = function(tid, limit, nested_limit, parent, lastcreated) {
142-
if (typeof(limit) === 'undefined') { limit = "inf"; }
143-
if (typeof(nested_limit) === 'undefined') { nested_limit = "inf"; }
144-
if (typeof(parent) === 'undefined') { parent = null; }
141+
var fetch = function({ tid, limit = "inf", nested_limit = "inf", parent = null, sort = "", offset = 0 }) {
142+
var query_dict = { uri: tid || location(), sort, parent, offset };
145143

146-
var query_dict = {uri: tid || location(), after: lastcreated, parent: parent};
147-
148-
if(limit !== "inf") {
144+
if (limit !== "inf") {
149145
query_dict['limit'] = limit;
150146
}
151-
if(nested_limit !== "inf"){
147+
if (nested_limit !== "inf") {
152148
query_dict['nested_limit'] = nested_limit;
153149
}
154150

isso/js/app/default_config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var default_config = {
1313
"max-comments-top": "inf",
1414
"max-comments-nested": 5,
1515
"reveal-on-click": 5,
16+
"sorting": "oldest",
1617
"gravatar": false,
1718
"avatar": true,
1819
"avatar-bg": "#f0f0f0",

isso/js/app/isso.js

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ var Postbox = function(parent) {
114114
notification: $("[name=notification]", el).checked() ? 1 : 0,
115115
}).then(function(comment) {
116116
$(".isso-textarea", el).value = "";
117-
insert(comment, true);
117+
insert({ comment, scrollIntoView: true, offset: 0 });
118118

119119
if (parent !== null) {
120120
el.onsuccess();
@@ -125,7 +125,7 @@ var Postbox = function(parent) {
125125
return el;
126126
};
127127

128-
var insert_loader = function(comment, lastcreated) {
128+
var insert_loader = function(comment, offset) {
129129
var entrypoint;
130130
if (comment.id === null) {
131131
entrypoint = $("#isso-root");
@@ -140,34 +140,37 @@ var insert_loader = function(comment, lastcreated) {
140140

141141
$("a.isso-load-hidden", el).on("click", function() {
142142
el.remove();
143-
api.fetch($("#isso-thread").getAttribute("data-isso-id"),
144-
config["reveal-on-click"], config["max-comments-nested"],
145-
comment.id,
146-
lastcreated).then(
143+
144+
api.fetch({
145+
tid: $("#isso-thread").getAttribute("data-isso-id"),
146+
limit: config["reveal-on-click"],
147+
nested_limit: config["max-comments-nested"],
148+
parent: comment.id,
149+
sort: config["sorting"],
150+
offset: offset
151+
}).then(
147152
function(rv) {
148153
if (rv.total_replies === 0) {
149154
return;
150155
}
151156

152-
var lastcreated = 0;
153157
rv.replies.forEach(function(commentObject) {
154-
insert(commentObject, false);
155-
if(commentObject.created > lastcreated) {
156-
lastcreated = commentObject.created;
157-
}
158+
insert({ comment: commentObject, scrollIntoView: false, offset: 0 });
159+
158160
});
159161

160162
if(rv.hidden_replies > 0) {
161-
insert_loader(rv, lastcreated);
163+
insert_loader(rv, offset + rv.replies.length);
162164
}
163165
},
164166
function(err) {
165167
console.log(err);
166-
});
168+
}
169+
);
167170
});
168171
};
169172

170-
var insert = function(comment, scrollIntoView) {
173+
var insert = function({ comment, scrollIntoView, offset }) {
171174
var el = $.htmlify(template.render("comment", {"comment": comment}));
172175

173176
// update datetime every 60 seconds
@@ -381,19 +384,13 @@ var insert = function(comment, scrollIntoView) {
381384
show($("a.isso-reply", footer).detach());
382385
}
383386

384-
if(comment.hasOwnProperty('replies')) {
385-
var lastcreated = 0;
386-
comment.replies.forEach(function(replyObject) {
387-
insert(replyObject, false);
388-
if(replyObject.created > lastcreated) {
389-
lastcreated = replyObject.created;
390-
}
391-
387+
if (comment.hasOwnProperty('replies')) {
388+
comment.replies.forEach(function (replyObject) {
389+
insert({ comment: replyObject, scrollIntoView: false, offset: offset + 1 });
392390
});
393-
if(comment.hidden_replies > 0) {
394-
insert_loader(comment, lastcreated);
391+
if (comment.hidden_replies > 0) {
392+
insert_loader(comment, offset + comment.replies.length);
395393
}
396-
397394
}
398395

399396
};

isso/js/embed.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,28 +122,30 @@ function fetchComments() {
122122
}
123123
isso_root.textContent = '';
124124

125-
api.fetch(isso_thread.getAttribute("data-isso-id") || location.pathname,
126-
config["max-comments-top"],
127-
config["max-comments-nested"]).then(
125+
126+
api.fetch({
127+
tid: isso_thread.getAttribute("data-isso-id") || location.pathname,
128+
limit: config["max-comments-top"],
129+
nested_limit: config["max-comments-nested"],
130+
parent: null,
131+
sort: config["sorting"],
132+
offset: 0
133+
}).then(
128134
function (rv) {
129135

130136
if (rv.total_replies === 0) {
131137
heading.textContent = i18n.translate("no-comments");
132138
return;
133139
}
134140

135-
var lastcreated = 0;
136141
var count = rv.total_replies;
137142
rv.replies.forEach(function(comment) {
138-
isso.insert(comment, false);
139-
if (comment.created > lastcreated) {
140-
lastcreated = comment.created;
141-
}
143+
isso.insert({ comment: comment, scrollIntoView: false, offset: 0 });
142144
});
143145
heading.textContent = i18n.pluralize("num-comments", count);
144146

145147
if (rv.hidden_replies > 0) {
146-
isso.insert_loader(rv, lastcreated);
148+
isso.insert_loader(rv, rv.replies.length);
147149
}
148150

149151
if (window.location.hash.length > 0 &&

isso/js/tests/unit/comment.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ test('Rendered comment should match snapshot', () => {
5858
var isso_thread = $('#isso-thread');
5959
isso_thread.append('<div id="isso-root"></div>');
6060

61-
isso.insert(comment, false);
61+
isso.insert({ comment, scrollIntoView: false, offset: 0 });
6262

6363
// Will create a `.snap` file in `./__snapshots__/`.
6464
// Don't forget to check in those files when changing anything!

0 commit comments

Comments
 (0)