Browse Source

Reset comments read marker after loading comments

tags/v9.0beta1
Vincent Petry 8 years ago
parent
commit
85bec3ffcb

+ 1
- 0
apps/comments/appinfo/app.php View File

@@ -27,6 +27,7 @@ $eventDispatcher->addListener(
\OCP\Util::addScript('comments', 'app');
\OCP\Util::addScript('comments', 'commentmodel');
\OCP\Util::addScript('comments', 'commentcollection');
\OCP\Util::addScript('comments', 'commentsummarymodel');
\OCP\Util::addScript('comments', 'commentstabview');
\OCP\Util::addScript('comments', 'filesplugin');
\OCP\Util::addStyle('comments', 'comments');

+ 59
- 2
apps/comments/js/commentcollection.js View File

@@ -10,8 +10,6 @@

(function(OC, OCA) {

var NS_OWNCLOUD = 'http://owncloud.org/ns';

/**
* @class OCA.Comments.CommentCollection
* @classdesc
@@ -26,12 +24,40 @@

model: OCA.Comments.CommentModel,

/**
* Object type
*
* @type string
*/
_objectType: 'files',

/**
* Object id
*
* @type string
*/
_objectId: null,

/**
* True if there are no more page results left to fetch
*
* @type bool
*/
_endReached: false,

/**
* Number of comments to fetch per page
*
* @type int
*/
_limit : 20,

/**
* Initializes the collection
*
* @param {string} [options.objectType] object type
* @param {string} [options.objectId] object id
*/
initialize: function(models, options) {
options = options || {};
if (options.objectType) {
@@ -58,6 +84,7 @@

reset: function() {
this._endReached = false;
this._summaryModel = null;
return OC.Backbone.Collection.prototype.reset.apply(this, arguments);
},

@@ -81,6 +108,7 @@
var success = options.success;
options = _.extend({
remove: false,
parse: true,
data: body,
davProperties: CommentCollection.prototype.model.prototype.davProperties,
success: function(resp) {
@@ -102,6 +130,35 @@
}, options);

return this.sync('REPORT', this, options);
},

/**
* Returns the matching summary model
*
* @return {OCA.Comments.CommentSummaryModel} summary model
*/
getSummaryModel: function() {
if (!this._summaryModel) {
this._summaryModel = new OCA.Comments.CommentSummaryModel({
id: this._objectId,
objectType: this._objectType
});
}
return this._summaryModel;
},

/**
* Updates the read marker for this comment thread
*
* @param {Date} [date] optional date, defaults to now
* @param {Object} [options] backbone options
*/
updateReadMarker: function(date, options) {
options = options || {};

return this.getSummaryModel().save({
readMarker: (date || new Date()).toUTCString()
}, options);
}
});


+ 3
- 2
apps/comments/js/commentmodel.js View File

@@ -34,11 +34,12 @@
'actorDisplayName': '{' + NS_OWNCLOUD + '}actorDisplayName',
'creationDateTime': '{' + NS_OWNCLOUD + '}creationDateTime',
'objectType': '{' + NS_OWNCLOUD + '}objectType',
'objectId': '{' + NS_OWNCLOUD + '}objectId'
'objectId': '{' + NS_OWNCLOUD + '}objectId',
'isUnread': '{' + NS_OWNCLOUD + '}isUnread'
},

parse: function(data) {
// TODO: parse non-string values
data.isUnread = (data.isUnread === 'true');
return data;
}
});

+ 24
- 3
apps/comments/js/commentstabview.js View File

@@ -31,7 +31,7 @@
'<div class="loading hidden" style="height: 50px"></div>';

var COMMENT_TEMPLATE =
'<li class="comment">' +
'<li class="comment{{#if isUnread}} unread{{/if}}" data-id="{{id}}">' +
' <div class="authorRow">' +
' {{#if avatarEnabled}}' +
' <div class="avatar" data-username="{{actorId}}"> </div>' +
@@ -97,12 +97,14 @@

setFileInfo: function(fileInfo) {
if (fileInfo) {
this.model = fileInfo;
this.render();
this.collection.setObjectId(fileInfo.id);
// reset to first page
this.collection.reset([], {silent: true});
this.nextPage();
} else {
this.model = null;
this.render();
this.collection.reset();
}
@@ -139,10 +141,29 @@
this.$el.find('.showMore').addClass('hidden');
},

_onEndRequest: function() {
_onEndRequest: function(type) {
var fileInfoModel = this.model;
this._toggleLoading(false);
this.$el.find('.empty').toggleClass('hidden', !!this.collection.length);
this.$el.find('.showMore').toggleClass('hidden', !this.collection.hasMoreResults());

if (type !== 'REPORT') {
return;
}

// find first unread comment
var firstUnreadComment = this.collection.findWhere({isUnread: true});
if (firstUnreadComment) {
// update read marker
this.collection.updateReadMarker(
null,
{
success: function() {
fileInfoModel.set('commentsUnread', 0);
}
}
);
}
},

_onAddModel: function(model, collection, options) {
@@ -210,7 +231,7 @@
actorType: 'users',
verb: 'comment',
message: $textArea.val(),
creationDateTime: (new Date()).getTime()
creationDateTime: (new Date()).toUTCString()
}, {
at: 0,
success: function() {

+ 65
- 0
apps/comments/js/commentsummarymodel.js View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2016
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/

(function(OC, OCA) {
var NS_OWNCLOUD = 'http://owncloud.org/ns';
/**
* @class OCA.Comments.CommentSummaryModel
* @classdesc
*
* Model containing summary information related to comments
* like the read marker.
*
*/
var CommentSummaryModel = OC.Backbone.Model.extend(
/** @lends OCA.Comments.CommentSummaryModel.prototype */ {
sync: OC.Backbone.davSync,

/**
* Object type
*
* @type string
*/
_objectType: 'files',

/**
* Object id
*
* @type string
*/
_objectId: null,

davProperties: {
'readMarker': '{' + NS_OWNCLOUD + '}readMarker'
},

/**
* Initializes the summary model
*
* @param {string} [options.objectType] object type
* @param {string} [options.objectId] object id
*/
initialize: function(attrs, options) {
options = options || {};
if (options.objectType) {
this._objectType = options.objectType;
}
},

url: function() {
return OC.linkToRemote('dav') + '/comments/' +
encodeURIComponent(this._objectType) + '/' +
encodeURIComponent(this.id) + '/';
}
});

OCA.Comments.CommentSummaryModel = CommentSummaryModel;
})(OC, OCA);


+ 44
- 0
apps/comments/tests/js/commentscollectionSpec.js View File

@@ -100,5 +100,49 @@ describe('OCA.Comments.CommentCollection', function() {

expect(collection.hasMoreResults()).toEqual(true);
});
describe('resetting read marker', function() {
var updateStub;
var clock;

beforeEach(function() {
updateStub = sinon.stub(OCA.Comments.CommentSummaryModel.prototype, 'save');
clock = sinon.useFakeTimers(Date.UTC(2016, 1, 3, 10, 5, 9));
});
afterEach(function() {
updateStub.restore();
clock.restore();
});
it('resets read marker to the default date', function() {
var successStub = sinon.stub();
collection.updateReadMarker(null, {
success: successStub
});

expect(updateStub.calledOnce).toEqual(true);
expect(updateStub.lastCall.args[0]).toEqual({
readMarker: new Date(Date.UTC(2016, 1, 3, 10, 5, 9)).toUTCString()
});

updateStub.yieldTo('success');

expect(successStub.calledOnce).toEqual(true);
});
it('resets read marker to the given date', function() {
var successStub = sinon.stub();
collection.updateReadMarker(new Date(Date.UTC(2016, 1, 2, 3, 4, 5)), {
success: successStub
});

expect(updateStub.calledOnce).toEqual(true);
expect(updateStub.lastCall.args[0]).toEqual({
readMarker: new Date(Date.UTC(2016, 1, 2, 3, 4, 5)).toUTCString()
});

updateStub.yieldTo('success');

expect(successStub.calledOnce).toEqual(true);
});
});
});


+ 38
- 4
apps/comments/tests/js/commentstabviewSpec.js View File

@@ -48,7 +48,7 @@ describe('OCA.Comments.CommentsTabView tests', function() {
objectType: 'files',
objectId: 5,
message: 'First',
creationDateTime: Date.UTC(2016, 1, 3, 10, 5, 0)
creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 5, 0)).toUTCString()
});
var comment2 = new OCA.Comments.CommentModel({
id: 2,
@@ -58,7 +58,7 @@ describe('OCA.Comments.CommentsTabView tests', function() {
objectType: 'files',
objectId: 5,
message: 'Second\nNewline',
creationDateTime: Date.UTC(2016, 1, 3, 10, 0, 0)
creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 0, 0)).toUTCString()
});

testComments = [comment1, comment2];
@@ -142,7 +142,7 @@ describe('OCA.Comments.CommentsTabView tests', function() {
objectType: 'files',
objectId: 5,
message: 'Third',
creationDateTime: Date.UTC(2016, 1, 3, 5, 0, 0)
creationDateTime: new Date(Date.UTC(2016, 1, 3, 5, 0, 0)).toUTCString()
});

view.collection.add(comment3);
@@ -184,7 +184,7 @@ describe('OCA.Comments.CommentsTabView tests', function() {
actorType: 'users',
verb: 'comment',
message: 'New message',
creationDateTime: Date.UTC(2016, 1, 3, 10, 5, 9)
creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 5, 9)).toUTCString()
});
});
it('does not create a comment if the field is empty', function() {
@@ -195,4 +195,38 @@ describe('OCA.Comments.CommentsTabView tests', function() {
});

});
describe('read marker', function() {
var updateMarkerStub;

beforeEach(function() {
updateMarkerStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'updateReadMarker');
});
afterEach(function() {
updateMarkerStub.restore();
});

it('resets the read marker after REPORT', function() {
testComments[0].set('isUnread', true, {silent: true});
testComments[1].set('isUnread', true, {silent: true});
view.collection.set(testComments);
view.collection.trigger('sync', 'REPORT');

expect(updateMarkerStub.calledOnce).toEqual(true);
expect(updateMarkerStub.lastCall.args[0]).toBeFalsy();
});
it('does not reset the read marker if there was no unread comments', function() {
view.collection.set(testComments);
view.collection.trigger('sync', 'REPORT');

expect(updateMarkerStub.notCalled).toEqual(true);
});
it('does not reset the read marker when posting comments', function() {
testComments[0].set('isUnread', true, {silent: true});
testComments[1].set('isUnread', true, {silent: true});
view.collection.set(testComments);
view.collection.trigger('sync', 'POST');

expect(updateMarkerStub.notCalled).toEqual(true);
});
});
});

+ 1
- 0
tests/karma.config.js View File

@@ -89,6 +89,7 @@ module.exports = function(config) {
'apps/comments/js/app.js',
'apps/comments/js/commentmodel.js',
'apps/comments/js/commentcollection.js',
'apps/comments/js/commentsummarymodel.js',
'apps/comments/js/commentstabview.js',
'apps/comments/js/filesplugin.js'
],

Loading…
Cancel
Save