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 0000000000000000000000000000000000000000..bf14372b906b0ec5d118f271634b994a1af6d77c --- /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 fb5978fda56e5ffdaff038ad3e91308f4aea747c..3586b8d35bf0586107495d030cd400617897d117 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 f7444f7d3c29f8c34385ee020e202fa960825199..7910e6e892d6943f9f2d777aedee30d570be6955 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 8d1e6b74c1afe40db6e51886c29c9b450415d475..96e727d4694f68ff1d71e9573510b457add568b4 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 29511a0a8d5e82b5b6940624a23c8a79322d03ac..8b273df695a72553cdea5305f607cfae5ae79988 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 adf09ce57498214adbc86613eea98276eca0066a..4bf2fdc2e32a9425b55c3d5a07149ac1c7185c73 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 f005f97e1f2f80e33c312b24427be0cb355ad425..6890ed137539997701a8a0dd1082f513ae3e3c1c 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 20b1a68c054dce67976ae83b43f881bb5e053709..c5c69da12df35c5096542f8f5a87d4016e334c8b 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 bc79db45e7f26fee2aa654571da9ac411c2669d8..d373f0760ec0254311a39d30ad7b6e7cd003890a 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 e8d5a5cc0b2cd991810b8b0abb18b61df79f7a4a..708b08f3023667d101c84fc30d7ba1efc424af8a 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 2d58ee66890b2f7b6f4464403870cff2c3cf3324..2351baaed2d3abb89d9202e8bfc8814fd7b0fde6 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 dd7806bfa70cc7505597477d5aa5a58ed2f413b4..a8c5e49b012e96dc9416f0e4f2acd0aa5e3b4bbb 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()