From d20291cd81dc912d0ca75b38b331e2e989a75fb8 Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Tue, 11 Jul 2023 17:33:36 -0300 Subject: [PATCH] Show notification for new blog posts and new post dot in sidebar --- .../briar/desktop/blog/BlogPostsReadEvent.kt | 23 +++++++++++++++ .../briar/desktop/blog/FeedViewModel.kt | 2 +- .../briar/desktop/navigation/BriarSidebar.kt | 2 +- .../desktop/navigation/SidebarViewModel.kt | 3 ++ .../AbstractNotificationProvider.kt | 6 +++- .../notification/NotificationProvider.kt | 4 ++- .../notification/SoundNotificationProvider.kt | 3 +- .../briarproject/briar/desktop/ui/BriarUi.kt | 11 +++++++ .../briar/desktop/ui/MessageCounter.kt | 4 +-- .../briar/desktop/ui/MessageCounterImpl.kt | 29 ++++++++++++++++++- .../resources/strings/BriarDesktop.properties | 1 + .../briar/desktop/TestRandomConversations.kt | 4 +-- 12 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogPostsReadEvent.kt diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogPostsReadEvent.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogPostsReadEvent.kt new file mode 100644 index 0000000000..bf14372b90 --- /dev/null +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogPostsReadEvent.kt @@ -0,0 +1,23 @@ +/* + * Briar Desktop + * Copyright (C) 2023 The Briar Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package org.briarproject.briar.desktop.blog + +import org.briarproject.bramble.api.event.Event + +data class BlogPostsReadEvent(val numPostsMarkedRead: Int) : Event() diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedViewModel.kt index fb5978fda5..3586b8d35b 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedViewModel.kt @@ -192,7 +192,7 @@ class FeedViewModel @Inject constructor( blogManager.setReadFlag(id, false) } // TODO introduce Transaction for BlogManager#setReadFlag() and attach event there -// eventBus.broadcast() + eventBus.broadcast(BlogPostsReadEvent(readIds.size)) } _posts.replaceIf({ it.id in readIds }) { when (it) { diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt index f7444f7d3c..7910e6e892 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt @@ -91,7 +91,7 @@ fun BriarSidebar( if (configuration.shouldEnablePrivateGroups()) BriarSidebarButton(UiMode.GROUPS, messageCount.privateGroupMessages) if (configuration.shouldEnableForums()) BriarSidebarButton(UiMode.FORUMS, messageCount.forumPosts) - if (configuration.shouldEnableBlogs()) BriarSidebarButton(UiMode.BLOGS) + if (configuration.shouldEnableBlogs()) BriarSidebarButton(UiMode.BLOGS, messageCount.blogPosts) Spacer(Modifier.weight(1f)) diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt index 8d1e6b74c1..96e727d469 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt @@ -28,6 +28,7 @@ import org.briarproject.bramble.api.mailbox.event.MailboxProblemEvent import org.briarproject.briar.desktop.threading.UiExecutor import org.briarproject.briar.desktop.ui.MessageCounter import org.briarproject.briar.desktop.ui.MessageCounterData +import org.briarproject.briar.desktop.ui.MessageCounterDataType.Blog import org.briarproject.briar.desktop.ui.MessageCounterDataType.Forum import org.briarproject.briar.desktop.ui.MessageCounterDataType.PrivateGroup import org.briarproject.briar.desktop.ui.MessageCounterDataType.PrivateMessage @@ -71,6 +72,7 @@ constructor( PrivateMessage -> _messageCount.update { copy(privateMessages = count) } Forum -> _messageCount.update { copy(forumPosts = count) } PrivateGroup -> _messageCount.update { copy(privateGroupMessages = count) } + Blog -> _messageCount.update { copy(blogPosts = count) } } } @@ -100,5 +102,6 @@ constructor( val privateMessages: Int = 0, val forumPosts: Int = 0, val privateGroupMessages: Int = 0, + val blogPosts: Int = 0, ) } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/AbstractNotificationProvider.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/AbstractNotificationProvider.kt index 29511a0a8d..8b273df695 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/AbstractNotificationProvider.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/AbstractNotificationProvider.kt @@ -1,6 +1,6 @@ /* * Briar Desktop - * Copyright (C) 2021-2022 The Briar Project + * Copyright (C) 2021-2023 The Briar Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -44,4 +44,8 @@ abstract class AbstractNotificationProvider : VisualNotificationProvider { else i18nF("notifications.message.group.several_groups", num, groups) ) + + override fun notifyBlogPosts(num: Int) = sendNotification( + i18nP("notifications.message.blog.posts", num) + ) } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/NotificationProvider.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/NotificationProvider.kt index adf09ce574..4bf2fdc2e3 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/NotificationProvider.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/NotificationProvider.kt @@ -1,6 +1,6 @@ /* * Briar Desktop - * Copyright (C) 2021-2022 The Briar Project + * Copyright (C) 2021-2023 The Briar Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -38,6 +38,7 @@ interface NotificationProvider { fun notifyPrivateMessages(num: Int, contacts: Int) fun notifyForumPosts(num: Int, forums: Int) fun notifyPrivateGroupMessages(num: Int, groups: Int) + fun notifyBlogPosts(num: Int) } interface VisualNotificationProvider : NotificationProvider @@ -54,4 +55,5 @@ object StubNotificationProvider : VisualNotificationProvider { override fun notifyPrivateMessages(num: Int, contacts: Int) {} override fun notifyForumPosts(num: Int, forums: Int) {} override fun notifyPrivateGroupMessages(num: Int, groups: Int) {} + override fun notifyBlogPosts(num: Int) {} } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/SoundNotificationProvider.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/SoundNotificationProvider.kt index f005f97e1f..6890ed1375 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/SoundNotificationProvider.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/notification/SoundNotificationProvider.kt @@ -1,6 +1,6 @@ /* * Briar Desktop - * Copyright (C) 2021-2022 The Briar Project + * Copyright (C) 2021-2023 The Briar Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -58,4 +58,5 @@ object SoundNotificationProvider : NotificationProvider { override fun notifyPrivateMessages(num: Int, contacts: Int) = playSound() override fun notifyForumPosts(num: Int, forums: Int) = playSound() override fun notifyPrivateGroupMessages(num: Int, groups: Int) = playSound() + override fun notifyBlogPosts(num: Int) = playSound() } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt index 20b1a68c05..c5c69da12d 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt @@ -56,6 +56,7 @@ import org.briarproject.briar.desktop.settings.Configuration import org.briarproject.briar.desktop.settings.UnencryptedSettings.Theme.AUTO import org.briarproject.briar.desktop.settings.UnencryptedSettings.Theme.DARK import org.briarproject.briar.desktop.theme.BriarTheme +import org.briarproject.briar.desktop.ui.MessageCounterDataType.Blog import org.briarproject.briar.desktop.ui.MessageCounterDataType.Forum import org.briarproject.briar.desktop.ui.MessageCounterDataType.PrivateGroup import org.briarproject.briar.desktop.ui.MessageCounterDataType.PrivateMessage @@ -141,6 +142,7 @@ constructor( var lastNotificationPrivateMessage = 0L var lastNotificationForum = 0L var lastNotificationPrivateGroup = 0L + var lastNotificationBlog = 0L val eventListener = EventListener { e -> when (e) { @@ -160,6 +162,7 @@ constructor( lastNotificationPrivateMessage = 0 lastNotificationForum = 0 lastNotificationPrivateGroup = 0 + lastNotificationBlog = 0 } } val messageCounterListener: MessageCounterListener = { (type, total, groups, inc) -> @@ -176,6 +179,10 @@ constructor( PrivateGroup -> { { notifyPrivateGroupMessages(total, groups) } } + + Blog -> { + { notifyBlogPosts(total) } + } } val (lastNotification, setLastNotification) = when (type) { PrivateMessage -> lastNotificationPrivateMessage to { v: Long -> @@ -187,6 +194,10 @@ constructor( PrivateGroup -> lastNotificationPrivateGroup to { v: Long -> lastNotificationPrivateGroup = v } + + Blog -> lastNotificationBlog to { v: Long -> + lastNotificationBlog = v + } } window.iconImage = iconBadge diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounter.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounter.kt index bc79db45e7..d373f0760e 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounter.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounter.kt @@ -1,6 +1,6 @@ /* * Briar Desktop - * Copyright (C) 2021-2022 The Briar Project + * Copyright (C) 2021-2023 The Briar Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -25,7 +25,7 @@ interface MessageCounter { fun removeListener(listener: MessageCounterListener): Boolean } -enum class MessageCounterDataType { PrivateMessage, Forum, PrivateGroup } +enum class MessageCounterDataType { PrivateMessage, Forum, PrivateGroup, Blog } /** * Data holder for MessageCounter updates. diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounterImpl.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounterImpl.kt index e8d5a5cc0b..708b08f302 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounterImpl.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounterImpl.kt @@ -28,20 +28,25 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RU import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent import org.briarproject.bramble.api.sync.GroupId import org.briarproject.bramble.api.sync.event.GroupRemovedEvent +import org.briarproject.briar.api.blog.BlogManager +import org.briarproject.briar.api.blog.event.BlogPostAddedEvent import org.briarproject.briar.api.conversation.ConversationManager import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent import org.briarproject.briar.api.forum.ForumManager import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent import org.briarproject.briar.api.privategroup.PrivateGroupManager import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent +import org.briarproject.briar.desktop.blog.BlogPostsReadEvent import org.briarproject.briar.desktop.conversation.ConversationMessagesReadEvent import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupMessageReadEvent import org.briarproject.briar.desktop.threading.BriarExecutors import org.briarproject.briar.desktop.threading.UiExecutor +import org.briarproject.briar.desktop.ui.MessageCounterDataType.Blog import org.briarproject.briar.desktop.ui.MessageCounterDataType.Forum import org.briarproject.briar.desktop.ui.MessageCounterDataType.PrivateGroup import org.briarproject.briar.desktop.ui.MessageCounterDataType.PrivateMessage import org.briarproject.briar.desktop.utils.KLoggerUtils.e +import org.briarproject.briar.desktop.utils.getRandomId import javax.inject.Inject class MessageCounterImpl @@ -51,6 +56,7 @@ constructor( private val conversationManager: ConversationManager, private val forumManager: ForumManager, private val privateGroupManager: PrivateGroupManager, + private val blogManager: BlogManager, private val briarExecutors: BriarExecutors, eventBus: EventBus, ) : MessageCounter { @@ -68,6 +74,10 @@ constructor( @UiExecutor private val countPrivateGroupMessages = Multiset<GroupId>() + @UiExecutor + private var countBlogPosts: Int = 0 + private val fakeBlogGroupId: GroupId = GroupId(getRandomId()) + private val listeners = mutableListOf<MessageCounterListener>() init { @@ -85,6 +95,9 @@ constructor( val countPrivateGroupMessageMap = privateGroupManager.getPrivateGroups(txn).associate { g -> g.id to privateGroupManager.getGroupCount(txn, g.id).unreadCount } + val blogPosts = blogManager.getBlogIds(txn).flatMap { b -> + blogManager.getPostHeaders(txn, b) + } txn.attach { countPrivateMessagesMap.forEach { (id, count) -> countPrivateMessages.addCount(id, count) @@ -95,10 +108,11 @@ constructor( countPrivateGroupMessageMap.forEach { (id, count) -> countPrivateGroupMessages.addCount(id, count) } - + countBlogPosts = blogPosts.count { post -> !post.isRead } informListeners(PrivateMessage, true) informListeners(Forum, true) informListeners(PrivateGroup, true) + informListeners(Blog, true) } } } @@ -137,6 +151,13 @@ constructor( informListeners(PrivateGroup, true) } + is BlogPostAddedEvent -> { + if (e.isLocal) return@addListener + + countBlogPosts++ + informListeners(Blog, true) + } + is ThreadedGroupMessageReadEvent -> { try { when (e.clientId) { @@ -158,6 +179,11 @@ constructor( } } + is BlogPostsReadEvent -> { + countBlogPosts -= e.numPostsMarkedRead + informListeners(Blog, false) + } + is GroupRemovedEvent -> { when (e.group.clientId) { ForumManager.CLIENT_ID -> { @@ -184,6 +210,7 @@ constructor( PrivateMessage -> countPrivateMessages Forum -> countForumPosts PrivateGroup -> countPrivateGroupMessages + Blog -> Multiset<GroupId>().apply { addCount(fakeBlogGroupId, countBlogPosts) } } l.invoke(MessageCounterData(type, groupCount.total, groupCount.unique, increment)) } diff --git a/briar-desktop/src/main/resources/strings/BriarDesktop.properties b/briar-desktop/src/main/resources/strings/BriarDesktop.properties index 2d58ee6689..2351baaed2 100644 --- a/briar-desktop/src/main/resources/strings/BriarDesktop.properties +++ b/briar-desktop/src/main/resources/strings/BriarDesktop.properties @@ -443,6 +443,7 @@ notifications.message.forum.one_forum={0, plural, one {New forum post.} other {{ notifications.message.forum.several_forums={0} new posts in {1} forums. notifications.message.group.one_group={0, plural, one {New private group message.} other {{0} new private group messages.}} notifications.message.group.several_groups={0} new messages in {1} private groups. +notifications.message.blog.posts={0, plural, one {New blog post.} other {{0} new blog posts.}} # Settings settings.title=Settings diff --git a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/TestRandomConversations.kt b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/TestRandomConversations.kt index dd7806bfa7..a8c5e49b01 100644 --- a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/TestRandomConversations.kt +++ b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/TestRandomConversations.kt @@ -1,6 +1,6 @@ /* * Briar Desktop - * Copyright (C) 2021-2022 The Briar Project + * Copyright (C) 2021-2023 The Briar Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -19,5 +19,5 @@ package org.briarproject.briar.desktop fun main() = RunWithTemporaryAccount { - getTestDataCreator().createTestData(5, 20, 50, 4, 4, 23, 4, 23) + getTestDataCreator().createTestData(5, 20, 50, 10, 4, 23, 4, 23) }.run() -- GitLab