Show comment counter and highlight if unread comments are available

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl
2021-04-28 13:22:23 +02:00
parent 0a9c846ae9
commit bbf0394df2
6 changed files with 38 additions and 8 deletions

View File

@@ -22,7 +22,9 @@
.icon-activity { .icon-activity {
@include icon-color('activity-dark', 'activity', $color-black); @include icon-color('activity-dark', 'activity', $color-black);
} }
.icon-comment--unread {
@include icon-color('comment', 'actions', $color-primary, 1, true);
}
.avatardiv.circles { .avatardiv.circles {
background: var(--color-primary); background: var(--color-primary);

View File

@@ -49,6 +49,7 @@ class Card extends RelationalEntity {
protected $notified = false; protected $notified = false;
protected $deletedAt = 0; protected $deletedAt = 0;
protected $commentsUnread = 0; protected $commentsUnread = 0;
protected $commentsCount = 0;
protected $relatedStack = null; protected $relatedStack = null;
protected $relatedBoard = null; protected $relatedBoard = null;
@@ -75,6 +76,7 @@ class Card extends RelationalEntity {
$this->addRelation('attachmentCount'); $this->addRelation('attachmentCount');
$this->addRelation('participants'); $this->addRelation('participants');
$this->addRelation('commentsUnread'); $this->addRelation('commentsUnread');
$this->addRelation('commentsCount');
$this->addResolvable('owner'); $this->addResolvable('owner');
$this->addRelation('relatedStack'); $this->addRelation('relatedStack');

View File

@@ -105,8 +105,10 @@ class CardService {
$card->setAttachmentCount($this->attachmentService->count($cardId)); $card->setAttachmentCount($this->attachmentService->count($cardId));
$user = $this->userManager->get($this->currentUser); $user = $this->userManager->get($this->currentUser);
$lastRead = $this->commentsManager->getReadMark('deckCard', (string)$card->getId(), $user); $lastRead = $this->commentsManager->getReadMark('deckCard', (string)$card->getId(), $user);
$count = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId(), $lastRead); $countUnreadComments = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId(), $lastRead);
$card->setCommentsUnread($count); $countComments = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId());
$card->setCommentsUnread($countUnreadComments);
$card->setCommentsCount($countComments);
$stack = $this->stackMapper->find($card->getStackId()); $stack = $this->stackMapper->find($card->getStackId());
$board = $this->boardService->find($stack->getBoardId()); $board = $this->boardService->find($stack->getBoardId());

View File

@@ -22,7 +22,13 @@
<template> <template>
<div v-if="card" class="badges"> <div v-if="card" class="badges">
<div v-if="card.commentsUnread > 0" class="icon icon-comment" /> <div v-if="card.commentsCount > 0"
v-tooltip="commentsHint"
class="icon icon-comment"
:class="{ 'icon-comment--unread': card.commentsUnread > 0 }"
@click.stop="openComments">
{{ card.commentsCount }}
</div>
<div v-if="card.description && checkListCount > 0" class="card-tasks icon icon-checkmark"> <div v-if="card.description && checkListCount > 0" class="card-tasks icon icon-checkmark">
{{ checkListCheckedCount }}/{{ checkListCount }} {{ checkListCheckedCount }}/{{ checkListCount }}
@@ -58,6 +64,21 @@ export default {
checkListCheckedCount() { checkListCheckedCount() {
return (this.card.description.match(/^\s*([*+-]|(\d\.))\s+\[\s*x\s*\](.*)$/gim) || []).length return (this.card.description.match(/^\s*([*+-]|(\d\.))\s+\[\s*x\s*\](.*)$/gim) || []).length
}, },
commentsHint() {
if (this.card.commentsUnread > 0) {
return t('deck', '{count} comments, {unread} unread', {
count: this.card.commentsCount,
unread: this.card.commentsUnread
})
}
return null
},
},
methods: {
openComments() {
const boardId = this.card && this.card.boardId ? this.card.boardId : this.$route.params.id
this.$router.push({ name: 'card', params: { id: boardId, cardId: this.card.id, tabId: 'comments' } })
},
}, },
} }
</script> </script>
@@ -70,7 +91,7 @@ export default {
.icon { .icon {
opacity: 0.5; opacity: 0.5;
padding: 12px 18px; padding: 10px 20px;
padding-right: 4px; padding-right: 4px;
margin-right: 5px; margin-right: 5px;
background-position: left; background-position: left;
@@ -78,8 +99,8 @@ export default {
span { span {
margin-left: 18px; margin-left: 18px;
} }
&.icon-edit { &.icon-comment--unread {
opacity: 0.5; opacity: 1;
} }
} }
} }

View File

@@ -83,6 +83,7 @@ class CardTest extends TestCase {
'assignedUsers' => null, 'assignedUsers' => null,
'deletedAt' => 0, 'deletedAt' => 0,
'commentsUnread' => 0, 'commentsUnread' => 0,
'commentsCount' => 0,
'lastEditor' => null, 'lastEditor' => null,
'ETag' => $card->getETag(), 'ETag' => $card->getETag(),
], $card->jsonSerialize()); ], $card->jsonSerialize());
@@ -109,6 +110,7 @@ class CardTest extends TestCase {
'assignedUsers' => null, 'assignedUsers' => null,
'deletedAt' => 0, 'deletedAt' => 0,
'commentsUnread' => 0, 'commentsUnread' => 0,
'commentsCount' => 0,
'lastEditor' => null, 'lastEditor' => null,
'ETag' => $card->getETag(), 'ETag' => $card->getETag(),
], $card->jsonSerialize()); ], $card->jsonSerialize());
@@ -145,6 +147,7 @@ class CardTest extends TestCase {
'assignedUsers' => ['user1'], 'assignedUsers' => ['user1'],
'deletedAt' => 0, 'deletedAt' => 0,
'commentsUnread' => 0, 'commentsUnread' => 0,
'commentsCount' => 0,
'lastEditor' => null, 'lastEditor' => null,
'ETag' => $card->getETag(), 'ETag' => $card->getETag(),
], $card->jsonSerialize()); ], $card->jsonSerialize());

View File

@@ -128,7 +128,7 @@ class CardServiceTest extends TestCase {
$this->userManager->expects($this->once()) $this->userManager->expects($this->once())
->method('get') ->method('get')
->willReturn($user); ->willReturn($user);
$this->commentsManager->expects($this->once()) $this->commentsManager->expects($this->any())
->method('getNumberOfCommentsForObject') ->method('getNumberOfCommentsForObject')
->willReturn(0); ->willReturn(0);
$boardMock = $this->createMock(Board::class); $boardMock = $this->createMock(Board::class);