From cc03c378e6d5c713aea50ac8930a1dae0ad1cb88 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Wed, 1 Jul 2020 18:56:14 +0200 Subject: [PATCH] =?utf8?q?=E2=99=BB=EF=B8=8F=20Extract=20interface=20for?= =?utf8?q?=20list=20notification=20filter?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../sone/notify/DefaultListNotificationFilter.kt | 90 ++++++++++++++++++++++ .../sone/notify/ListNotificationFilter.kt | 70 ++--------------- .../sone/notify/ListNotificationFilterTest.kt | 14 ++-- 3 files changed, 103 insertions(+), 71 deletions(-) create mode 100644 src/main/kotlin/net/pterodactylus/sone/notify/DefaultListNotificationFilter.kt diff --git a/src/main/kotlin/net/pterodactylus/sone/notify/DefaultListNotificationFilter.kt b/src/main/kotlin/net/pterodactylus/sone/notify/DefaultListNotificationFilter.kt new file mode 100644 index 0000000..acd2bce --- /dev/null +++ b/src/main/kotlin/net/pterodactylus/sone/notify/DefaultListNotificationFilter.kt @@ -0,0 +1,90 @@ +/* + * Sone - DefaultListNotificationFilter.kt - Copyright © 2010–2020 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.pterodactylus.sone.notify + +import net.pterodactylus.sone.data.Post +import net.pterodactylus.sone.data.PostReply +import net.pterodactylus.sone.data.Sone +import net.pterodactylus.sone.utils.ifTrue +import net.pterodactylus.util.notify.Notification +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Filter for [ListNotification]s. + */ +@Singleton +class DefaultListNotificationFilter @Inject constructor(private val postVisibilityFilter: PostVisibilityFilter, private val replyVisibilityFilter: ReplyVisibilityFilter) : ListNotificationFilter { + + /** + * Filters new-post and new-reply notifications in the given list of + * notifications. If `currentSone` is `null`, new-post and + * new-reply notifications are removed completely. If `currentSone` is + * not `null`, only posts that are posted by a friend Sone or the Sone + * itself, and replies that are replies to posts of friend Sones or the Sone + * itself will be retained in the notifications. + * + * @param notifications + * The notifications to filter + * @param currentSone + * The current Sone, or `null` if not logged in + * @return The filtered notifications + */ + override fun filterNotifications(notifications: Collection, currentSone: Sone?) = + notifications.mapNotNull { it.filtered(currentSone) } + + @Suppress("UNCHECKED_CAST") + private fun Notification.filtered(currentSone: Sone?): Notification? = when { + isNewSoneNotification -> { + takeIf { currentSone == null || currentSone.options.isShowNewSoneNotifications } + } + isNewPostNotification -> { + (currentSone != null && currentSone.options.isShowNewPostNotifications).ifTrue { + (this as ListNotification).filterNotification { postVisibilityFilter.isPostVisible(currentSone, it) } + } + } + isNewReplyNotification -> { + (currentSone != null && currentSone.options.isShowNewReplyNotifications).ifTrue { + (this as ListNotification).filterNotification { replyVisibilityFilter.isReplyVisible(currentSone, it) } + } + } + isMentionNotification -> { + (this as ListNotification).filterNotification { postVisibilityFilter.isPostVisible(currentSone, it) } + } + else -> this + } + +} + +/** + * Filters the elements of this list notification. + * + * @param filter The filter for the notification’s elements + * @return A list notification containing the filtered elements, or `null` + * if the notification does not have any elements after filtering + */ +private fun ListNotification.filterNotification(filter: (T) -> Boolean) = + elements.filter(filter).let { filteredElements -> + when (filteredElements.size) { + 0 -> null + elements.size -> this + else -> ListNotification(this).apply { + setElements(filteredElements) + setLastUpdateTime(lastUpdatedTime) + } + } + } diff --git a/src/main/kotlin/net/pterodactylus/sone/notify/ListNotificationFilter.kt b/src/main/kotlin/net/pterodactylus/sone/notify/ListNotificationFilter.kt index aedb180..63041f6 100644 --- a/src/main/kotlin/net/pterodactylus/sone/notify/ListNotificationFilter.kt +++ b/src/main/kotlin/net/pterodactylus/sone/notify/ListNotificationFilter.kt @@ -16,75 +16,17 @@ */ package net.pterodactylus.sone.notify -import net.pterodactylus.sone.data.Post -import net.pterodactylus.sone.data.PostReply +import com.google.inject.ImplementedBy import net.pterodactylus.sone.data.Sone -import net.pterodactylus.sone.utils.ifTrue import net.pterodactylus.util.notify.Notification -import javax.inject.Inject -import javax.inject.Singleton /** - * Filter for [ListNotification]s. + * Filters [list notifications][ListNotification], depending on the current + * [Sone] and [its options][Sone.getOptions]. */ -@Singleton -class ListNotificationFilter @Inject constructor(private val postVisibilityFilter: PostVisibilityFilter, private val replyVisibilityFilter: ReplyVisibilityFilter) { +@ImplementedBy(DefaultListNotificationFilter::class) +interface ListNotificationFilter { - /** - * Filters new-post and new-reply notifications in the given list of - * notifications. If `currentSone` is `null`, new-post and - * new-reply notifications are removed completely. If `currentSone` is - * not `null`, only posts that are posted by a friend Sone or the Sone - * itself, and replies that are replies to posts of friend Sones or the Sone - * itself will be retained in the notifications. - * - * @param notifications - * The notifications to filter - * @param currentSone - * The current Sone, or `null` if not logged in - * @return The filtered notifications - */ - fun filterNotifications(notifications: Collection, currentSone: Sone?) = - notifications.mapNotNull { it.filtered(currentSone) } - - @Suppress("UNCHECKED_CAST") - private fun Notification.filtered(currentSone: Sone?): Notification? = when { - isNewSoneNotification -> { - takeIf { currentSone == null || currentSone.options.isShowNewSoneNotifications } - } - isNewPostNotification -> { - (currentSone != null && currentSone.options.isShowNewPostNotifications).ifTrue { - (this as ListNotification).filterNotification { postVisibilityFilter.isPostVisible(currentSone, it) } - } - } - isNewReplyNotification -> { - (currentSone != null && currentSone.options.isShowNewReplyNotifications).ifTrue { - (this as ListNotification).filterNotification { replyVisibilityFilter.isReplyVisible(currentSone, it) } - } - } - isMentionNotification -> { - (this as ListNotification).filterNotification { postVisibilityFilter.isPostVisible(currentSone, it) } - } - else -> this - } + fun filterNotifications(notifications: Collection, currentSone: Sone?): Collection } - -/** - * Filters the elements of this list notification. - * - * @param filter The filter for the notification’s elements - * @return A list notification containing the filtered elements, or `null` - * if the notification does not have any elements after filtering - */ -private fun ListNotification.filterNotification(filter: (T) -> Boolean) = - elements.filter(filter).let { filteredElements -> - when (filteredElements.size) { - 0 -> null - elements.size -> this - else -> ListNotification(this).apply { - setElements(filteredElements) - setLastUpdateTime(lastUpdatedTime) - } - } - } diff --git a/src/test/kotlin/net/pterodactylus/sone/notify/ListNotificationFilterTest.kt b/src/test/kotlin/net/pterodactylus/sone/notify/ListNotificationFilterTest.kt index 67a01c3..ffc1e5a 100644 --- a/src/test/kotlin/net/pterodactylus/sone/notify/ListNotificationFilterTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/notify/ListNotificationFilterTest.kt @@ -23,7 +23,7 @@ import org.junit.Test */ class ListNotificationFilterTest { - private val listNotificationFilter = ListNotificationFilter(showAllPosts, showAllReplies) + private val listNotificationFilter = DefaultListNotificationFilter(showAllPosts, showAllReplies) @Test fun `filter is only created once`() { @@ -72,7 +72,7 @@ class ListNotificationFilterTest { localSone.options.isShowNewPostNotifications = true val newPostNotification = createNewPostNotification() newPostNotification.add(createPost()) - val listNotificationFilter = ListNotificationFilter(showNoPosts, showAllReplies) + val listNotificationFilter = DefaultListNotificationFilter(showNoPosts, showAllReplies) val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), localSone) assertThat(filteredNotifications, emptyIterable()) } @@ -104,7 +104,7 @@ class ListNotificationFilterTest { val newPostNotification = createNewPostNotification() newPostNotification.add(createPost()) newPostNotification.add(createPost()) - val listNotificationFilter = ListNotificationFilter(matchThisPost(newPostNotification.elements[1]), showAllReplies) + val listNotificationFilter = DefaultListNotificationFilter(matchThisPost(newPostNotification.elements[1]), showAllReplies) val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), localSone) assertThat((filteredNotifications[0] as ListNotification).elements, contains(newPostNotification.elements[1])) } @@ -116,7 +116,7 @@ class ListNotificationFilterTest { val newReplyNotification = createNewReplyNotification() newReplyNotification.add(createPostReply()) newReplyNotification.add(createPostReply()) - val listNotificationFilter = ListNotificationFilter(showAllPosts, matchThisReply(newReplyNotification.elements[1])) + val listNotificationFilter = DefaultListNotificationFilter(showAllPosts, matchThisReply(newReplyNotification.elements[1])) val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newReplyNotification), localSone) assertThat(filteredNotifications, hasSize(1)) assertThat((filteredNotifications[0] as ListNotification).elements[0], equalTo(newReplyNotification.elements[1])) @@ -140,7 +140,7 @@ class ListNotificationFilterTest { val newReplyNotification = createNewReplyNotification() newReplyNotification.add(createPostReply()) newReplyNotification.add(createPostReply()) - val listNotificationFilter = ListNotificationFilter(showAllPosts, showNoReplies) + val listNotificationFilter = DefaultListNotificationFilter(showAllPosts, showNoReplies) val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newReplyNotification), localSone) assertThat(filteredNotifications, emptyIterable()) } @@ -170,7 +170,7 @@ class ListNotificationFilterTest { val mentionNotification = createMentionNotification() mentionNotification.add(createPost()) mentionNotification.add(createPost()) - val listNotificationFilter = ListNotificationFilter(matchThisPost(mentionNotification.elements[1]), showAllReplies) + val listNotificationFilter = DefaultListNotificationFilter(matchThisPost(mentionNotification.elements[1]), showAllReplies) val filteredNotifications = listNotificationFilter.filterNotifications(listOf(mentionNotification), null) assertThat(filteredNotifications, hasSize(1)) assertThat((filteredNotifications[0] as ListNotification).elements[0], equalTo(mentionNotification.elements[1])) @@ -181,7 +181,7 @@ class ListNotificationFilterTest { val mentionNotification = createMentionNotification() mentionNotification.add(createPost()) mentionNotification.add(createPost()) - val listNotificationFilter = ListNotificationFilter(showNoPosts, showAllReplies) + val listNotificationFilter = DefaultListNotificationFilter(showNoPosts, showAllReplies) val filteredNotifications = listNotificationFilter.filterNotifications(listOf(mentionNotification), null) assertThat(filteredNotifications, emptyIterable()) } -- 2.7.4