diff options
| -rw-r--r-- | src/components/status/status.js | 57 | ||||
| -rw-r--r-- | src/components/status/status.vue | 18 | ||||
| -rw-r--r-- | src/i18n/en.json | 4 | ||||
| -rw-r--r-- | src/modules/statuses.js | 10 | ||||
| -rw-r--r-- | src/services/status_parser/status_parser.js | 11 |
5 files changed, 83 insertions, 17 deletions
diff --git a/src/components/status/status.js b/src/components/status/status.js index 9cd9d61c..95278968 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -12,7 +12,8 @@ import StatusPopover from '../status_popover/status_popover.vue' import EmojiReactions from '../emoji_reactions/emoji_reactions.vue' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js' -import { filter, unescape, uniqBy } from 'lodash' +import { muteWordHits } from '../../services/status_parser/status_parser.js' +import { unescape, uniqBy } from 'lodash' import { mapGetters, mapState } from 'vuex' const Status = { @@ -44,6 +45,12 @@ const Status = { muteWords () { return this.mergedConfig.muteWords }, + showReasonMutedThread () { + return ( + this.status.thread_muted || + (this.status.reblog && this.status.reblog.thread_muted) + ) && !this.inConversation + }, repeaterClass () { const user = this.statusoid.user return highlightClass(user) @@ -93,20 +100,44 @@ const Status = { return !!this.currentUser }, muteWordHits () { - const statusText = this.status.text.toLowerCase() - const statusSummary = this.status.summary.toLowerCase() - const hits = filter(this.muteWords, (muteWord) => { - return statusText.includes(muteWord.toLowerCase()) || statusSummary.includes(muteWord.toLowerCase()) - }) - - return hits + return muteWordHits(this.status, this.muteWords) }, muted () { - const relationship = this.$store.getters.relationship(this.status.user.id) - return !this.unmuted && ( - (!(this.inProfile && this.status.user.id === this.profileUserId) && relationship.muting) || - (!this.inConversation && this.status.thread_muted) || - this.muteWordHits.length > 0) + const { status } = this + const { reblog } = status + const relationship = this.$store.getters.relationship(status.user.id) + const relationshipReblog = reblog && this.$store.getters.relationship(reblog.user.id) + const reasonsToMute = ( + // Post is muted according to BE + status.muted || + // Reprööt of a muted post according to BE + (reblog && reblog.muted) || + // Muted user + relationship.muting || + // Muted user of a reprööt + (relationshipReblog && relationshipReblog.muting) || + // Thread is muted + status.thread_muted || + // Wordfiltered + this.muteWordHits.length > 0 + ) + const excusesNotToMute = ( + // Currently showing status + this.unmuted || + ( + this.inProfile && ( + // Don't mute user's posts on user timeline (except reblogs) + (!reblog && status.user.id === this.profileUserId) || + // Same as above but also allow self-reblogs + (reblog && reblog.user.id === this.profileUserId) + ) + ) || + // Don't mute statuses in muted conversation when said conversation is opened + (this.inConversation && status.thread_muted) + // No excuses if post has muted words + ) && !this.muteWordHits.length > 0 + + return !excusesNotToMute && reasonsToMute }, hideFilteredStatuses () { return this.mergedConfig.hideFilteredStatuses diff --git a/src/components/status/status.vue b/src/components/status/status.vue index e4c7545b..1c287aa7 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -18,10 +18,26 @@ <template v-if="muted && !isPreview"> <div class="media status container muted"> <small> + <i + v-if="muted && retweet" + class="button-icon icon-retweet" + /> <router-link :to="userProfileLink"> {{ status.user.screen_name }} </router-link> </small> + <small + v-if="showReasonMutedThread && muteWordHits.length === 0" + class="mutedThread" + > + {{ $t('status.thread_muted') }} + </small> + <small + v-if="showReasonMutedThread && muteWordHits.length > 0" + class="mutedThread" + > + {{ $t('status.thread_muted_and_words') }} + </small> <small class="muteWords">{{ muteWordHits.join(', ') }}</small> <a href="#" @@ -642,7 +658,7 @@ $status-margin: 0.75em; margin-left: auto; } - .muteWords { + .mutedThread, .muteWords { margin-left: 10px; } } diff --git a/src/i18n/en.json b/src/i18n/en.json index f5d1ce7c..61b818a6 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -621,7 +621,9 @@ "mute_conversation": "Mute conversation", "unmute_conversation": "Unmute conversation", "status_unavailable": "Status unavailable", - "copy_link": "Copy link to status" + "copy_link": "Copy link to status", + "thread_muted": "Conversation muted", + "thread_muted_and_words": "Conversation muted, contains filtered words:" }, "user_card": { "approve": "Approve", diff --git a/src/modules/statuses.js b/src/modules/statuses.js index cd8c1dba..f73fde25 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -15,7 +15,7 @@ import { import { set } from 'vue' import { isStatusNotification } from '../services/notification_utils/notification_utils.js' import apiService from '../services/api/api.service.js' -// import parse from '../services/status_parser/status_parser.js' +import { muteWordHits } from '../services/status_parser/status_parser.js' const emptyTl = (userId = 0) => ({ statuses: [], @@ -381,7 +381,13 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot notifObj.image = status.attachments[0].url } - if (!notification.seen && !state.notifications.desktopNotificationSilence && visibleNotificationTypes.includes(notification.type)) { + if ( + !notification.seen && + !state.notifications.desktopNotificationSilence && + visibleNotificationTypes.includes(notification.type) && + !status.muted && + muteWordHits(status, rootGetters.mergedConfig.muteWords).length === 0 + ) { let desktopNotification = new window.Notification(title, notifObj) // Chrome is known for not closing notifications automatically // according to MDN, anyway. diff --git a/src/services/status_parser/status_parser.js b/src/services/status_parser/status_parser.js index 900cd56e..3d517e3c 100644 --- a/src/services/status_parser/status_parser.js +++ b/src/services/status_parser/status_parser.js @@ -1,3 +1,4 @@ +import { filter } from 'lodash' import sanitize from 'sanitize-html' export const removeAttachmentLinks = (html) => { @@ -12,4 +13,14 @@ export const parse = (html) => { return removeAttachmentLinks(html) } +export const muteWordHits = (status, muteWords) => { + const statusText = status.text.toLowerCase() + const statusSummary = status.summary.toLowerCase() + const hits = filter(muteWords, (muteWord) => { + return statusText.includes(muteWord.toLowerCase()) || statusSummary.includes(muteWord.toLowerCase()) + }) + + return hits +} + export default parse |
