X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fkotlin%2Fnet%2Fpterodactylus%2Fsone%2Ftext%2FSoneMentionDetector.kt;h=3e15ed3cbffa5630150ed2bad6d114dc53f26154;hp=7dd82854b7dcfa597ceaf61f68e03adfc62953a2;hb=438378deab1514f0f608d975ef65f5b7aea44ccb;hpb=339671a5532a02cfbc25269b8ac3f13fc6a09295 diff --git a/src/main/kotlin/net/pterodactylus/sone/text/SoneMentionDetector.kt b/src/main/kotlin/net/pterodactylus/sone/text/SoneMentionDetector.kt index 7dd8285..3e15ed3 100644 --- a/src/main/kotlin/net/pterodactylus/sone/text/SoneMentionDetector.kt +++ b/src/main/kotlin/net/pterodactylus/sone/text/SoneMentionDetector.kt @@ -1,5 +1,5 @@ /** - * Sone - SoneMentionDetector.kt - Copyright © 2019 David ‘Bombe’ Roden + * Sone - SoneMentionDetector.kt - Copyright © 2019–2020 David ‘Bombe’ 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 @@ -19,26 +19,76 @@ package net.pterodactylus.sone.text import com.google.common.eventbus.* import net.pterodactylus.sone.core.event.* +import net.pterodactylus.sone.data.* +import net.pterodactylus.sone.database.* import net.pterodactylus.sone.utils.* import javax.inject.* /** * Listens to [NewPostFoundEvent]s and [NewPostReplyFoundEvent], parses the - * texts and emits a [LocalSoneMentionedInPostEvent] if a [SoneTextParser] + * texts and emits a [MentionOfLocalSoneFoundEvent] if a [SoneTextParser] * finds a [SonePart] that points to a local [Sone]. */ -class SoneMentionDetector @Inject constructor(private val eventBus: EventBus, private val soneTextParser: SoneTextParser) { +class SoneMentionDetector @Inject constructor(private val eventBus: EventBus, private val soneTextParser: SoneTextParser, private val postReplyProvider: PostReplyProvider) { @Subscribe fun onNewPost(newPostFoundEvent: NewPostFoundEvent) { newPostFoundEvent.post.let { post -> post.sone.isLocal.onFalse { - val parts = soneTextParser.parse(post.text, null) - if (parts.filterIsInstance().any { it.sone.isLocal }) { - eventBus.post(LocalSoneMentionedInPostEvent(post)) + if (post.text.hasLinksToLocalSones()) { + mentionedPosts += post + eventBus.post(MentionOfLocalSoneFoundEvent(post)) } } } } + @Subscribe + fun onNewPostReply(event: NewPostReplyFoundEvent) { + event.postReply.let { postReply -> + postReply.sone.isLocal.onFalse { + if (postReply.text.hasLinksToLocalSones()) { + postReply.post + .also { mentionedPosts += it } + .let(::MentionOfLocalSoneFoundEvent) + ?.also(eventBus::post) + } + } + } + } + + @Subscribe + fun onPostRemoved(event: PostRemovedEvent) { + unmentionPost(event.post) + } + + @Subscribe + fun onPostMarkedKnown(event: MarkPostKnownEvent) { + unmentionPost(event.post) + } + + @Subscribe + fun onReplyRemoved(event: PostReplyRemovedEvent) { + event.postReply.post.let { + if ((!it.text.hasLinksToLocalSones() || it.isKnown) && (it.replies.filterNot { it == event.postReply }.none { it.text.hasLinksToLocalSones() && !it.isKnown })) { + unmentionPost(it) + } + } + } + + private fun unmentionPost(post: Post) { + if (post in mentionedPosts) { + eventBus.post(MentionOfLocalSoneRemovedEvent(post)) + mentionedPosts -= post + } + } + + private val mentionedPosts = mutableSetOf() + + private fun String.hasLinksToLocalSones() = soneTextParser.parse(this, null) + .filterIsInstance() + .any { it.sone.isLocal } + + private val Post.replies get() = postReplyProvider.getReplies(id) + }