@@ -49,3 +49,7 @@ | |||
position: absolute; | |||
right: 0; | |||
} | |||
.app-files .action-comment>img { | |||
margin-right: 5px; | |||
} |
@@ -8,7 +8,15 @@ | |||
* | |||
*/ | |||
/* global Handlebars */ | |||
(function() { | |||
var TEMPLATE_COMMENTS_UNREAD = | |||
'<a class="action action-comment permanent" title="{{countMessage}}" href="#">' + | |||
'<img class="svg" src="{{iconUrl}}"/>' + | |||
'{{count}}' + | |||
'</a>'; | |||
OCA.Comments = _.extend({}, OCA.Comments); | |||
if (!OCA.Comments) { | |||
/** | |||
@@ -26,12 +34,88 @@ | |||
'favorites' | |||
], | |||
_formatCommentCount: function(count) { | |||
if (!this._commentsUnreadTemplate) { | |||
this._commentsUnreadTemplate = Handlebars.compile(TEMPLATE_COMMENTS_UNREAD); | |||
} | |||
return this._commentsUnreadTemplate({ | |||
count: count, | |||
countMessage: t('comments', '{count} unread comments', {count: count}), | |||
iconUrl: OC.imagePath('core', 'actions/comment') | |||
}); | |||
}, | |||
attach: function(fileList) { | |||
var self = this; | |||
if (this.allowedLists.indexOf(fileList.id) < 0) { | |||
return; | |||
} | |||
fileList.registerTabView(new OCA.Comments.CommentsTabView('commentsTabView')); | |||
var NS_OC = 'http://owncloud.org/ns'; | |||
var oldGetWebdavProperties = fileList._getWebdavProperties; | |||
fileList._getWebdavProperties = function() { | |||
var props = oldGetWebdavProperties.apply(this, arguments); | |||
props.push('{' + NS_OC + '}comments-unread'); | |||
return props; | |||
}; | |||
fileList.filesClient.addFileInfoParser(function(response) { | |||
var data = {}; | |||
var props = response.propStat[0].properties; | |||
var commentsUnread = props['{' + NS_OC + '}comments-unread']; | |||
if (!_.isUndefined(commentsUnread) && commentsUnread !== '') { | |||
data.commentsUnread = parseInt(commentsUnread, 10); | |||
} | |||
return data; | |||
}); | |||
fileList.$el.addClass('has-comments'); | |||
var oldCreateRow = fileList._createRow; | |||
fileList._createRow = function(fileData) { | |||
var $tr = oldCreateRow.apply(this, arguments); | |||
if (fileData.commentsUnread) { | |||
$tr.attr('data-comments-unread', fileData.commentsUnread); | |||
} | |||
return $tr; | |||
}; | |||
// register "comment" action for reading comments | |||
fileList.fileActions.registerAction({ | |||
name: 'Comment', | |||
displayName: t('comments', 'Comment'), | |||
mime: 'all', | |||
permissions: OC.PERMISSION_READ, | |||
type: OCA.Files.FileActions.TYPE_INLINE, | |||
render: function(actionSpec, isDefault, context) { | |||
var $file = context.$file; | |||
var unreadComments = $file.data('comments-unread'); | |||
if (unreadComments) { | |||
var $actionLink = $(self._formatCommentCount(unreadComments)); | |||
context.$file.find('a.name>span.fileactions').append($actionLink); | |||
return $actionLink; | |||
} | |||
return ''; | |||
}, | |||
actionHandler: function(fileName, context) { | |||
context.$file.find('.action-comment').tooltip('hide'); | |||
// open sidebar in comments section | |||
context.fileList.showDetailsView(fileName, 'commentsTabView'); | |||
} | |||
}); | |||
// add attribute to "elementToFile" | |||
var oldElementToFile = fileList.elementToFile; | |||
fileList.elementToFile = function($el) { | |||
var fileInfo = oldElementToFile.apply(this, arguments); | |||
var commentsUnread = $el.data('comments-unread'); | |||
if (commentsUnread) { | |||
fileInfo.commentsUnread = commentsUnread; | |||
} | |||
return fileInfo; | |||
}; | |||
} | |||
}; | |||
@@ -0,0 +1,102 @@ | |||
/* | |||
* Copyright (c) 2016 Vincent Petry <pvince81@owncloud.com> | |||
* | |||
* This file is licensed under the Affero General Public License version 3 | |||
* or later. | |||
* | |||
* See the COPYING-README file. | |||
* | |||
*/ | |||
describe('OCA.Comments.FilesPlugin tests', function() { | |||
var fileList; | |||
var testFiles; | |||
beforeEach(function() { | |||
var $content = $('<div id="content"></div>'); | |||
$('#testArea').append($content); | |||
// dummy file list | |||
var $div = $( | |||
'<div>' + | |||
'<table id="filestable">' + | |||
'<thead></thead>' + | |||
'<tbody id="fileList"></tbody>' + | |||
'</table>' + | |||
'</div>'); | |||
$('#content').append($div); | |||
fileList = new OCA.Files.FileList($div); | |||
OCA.Comments.FilesPlugin.attach(fileList); | |||
testFiles = [{ | |||
id: 1, | |||
type: 'file', | |||
name: 'One.txt', | |||
path: '/subdir', | |||
mimetype: 'text/plain', | |||
size: 12, | |||
permissions: OC.PERMISSION_ALL, | |||
etag: 'abc', | |||
shareOwner: 'User One', | |||
isShareMountPoint: false, | |||
commentsUnread: 3 | |||
}]; | |||
}); | |||
afterEach(function() { | |||
fileList.destroy(); | |||
fileList = null; | |||
}); | |||
describe('Comment icon', function() { | |||
it('does not render icon when no unread comments available', function() { | |||
testFiles[0].commentsUnread = 0; | |||
fileList.setFiles(testFiles); | |||
var $tr = fileList.findFileEl('One.txt'); | |||
expect($tr.find('.action-comment').length).toEqual(0); | |||
}); | |||
it('renders comment icon and extra data', function() { | |||
var $action, $tr; | |||
fileList.setFiles(testFiles); | |||
$tr = fileList.findFileEl('One.txt'); | |||
$action = $tr.find('.action-comment'); | |||
expect($action.length).toEqual(1); | |||
expect($action.hasClass('permanent')).toEqual(true); | |||
expect($tr.attr('data-comments-unread')).toEqual('3'); | |||
}); | |||
it('clicking icon opens sidebar', function() { | |||
var sidebarStub = sinon.stub(fileList, 'showDetailsView'); | |||
var $action, $tr; | |||
fileList.setFiles(testFiles); | |||
$tr = fileList.findFileEl('One.txt'); | |||
$action = $tr.find('.action-comment'); | |||
$action.click(); | |||
expect(sidebarStub.calledOnce).toEqual(true); | |||
expect(sidebarStub.lastCall.args[0]).toEqual('One.txt'); | |||
expect(sidebarStub.lastCall.args[1]).toEqual('commentsTabView'); | |||
}); | |||
}); | |||
describe('elementToFile', function() { | |||
it('returns comment count', function() { | |||
fileList.setFiles(testFiles); | |||
var $tr = fileList.findFileEl('One.txt'); | |||
var data = fileList.elementToFile($tr); | |||
expect(data.commentsUnread).toEqual(3); | |||
}); | |||
it('does not set comment count when not set', function() { | |||
delete testFiles[0].commentsUnread; | |||
fileList.setFiles(testFiles); | |||
var $tr = fileList.findFileEl('One.txt'); | |||
var data = fileList.elementToFile($tr); | |||
expect(data.commentsUnread).not.toBeDefined(); | |||
}); | |||
it('does not set comment count when zero', function() { | |||
testFiles[0].commentsUnread = 0; | |||
fileList.setFiles(testFiles); | |||
var $tr = fileList.findFileEl('One.txt'); | |||
var data = fileList.elementToFile($tr); | |||
expect(data.commentsUnread).not.toBeDefined(); | |||
}); | |||
}); | |||
}); |
@@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> | |||
<path style="color:#000000;block-progression:tb;text-transform:none;text-indent:0" d="m2.3496 1.002c-0.1975 0.0382-0.3531 0.2333-0.3496 0.4375v13.122c0 0.23 0.2061 0.438 0.4316 0.438h11.138c0.226 0 0.432-0.208 0.432-0.438v-10.142c-0.004-0.0669-0.023-0.133-0.055-0.1915l-3.312-3.1992c-0.043-0.0164-0.089-0.0255-0.135-0.0273h-8.0684c-0.0268-0.00265-0.0552-0.00265-0.082 0zm1.6504 1.998h6v1h-6v-1zm0 3h5v1h-5v-1zm0 3h8v1h-8v-1zm0 3h4v1h-4v-1z"/> | |||
</svg> |
@@ -90,7 +90,7 @@ module.exports = function(config) { | |||
'apps/comments/js/commentmodel.js', | |||
'apps/comments/js/commentcollection.js', | |||
'apps/comments/js/commentstabview.js', | |||
'apps/comments/js/filesplugin' | |||
'apps/comments/js/filesplugin.js' | |||
], | |||
testFiles: ['apps/comments/tests/js/**/*.js'] | |||
}, |