implement new muting

This commit is contained in:
Henry Jameson 2025-03-25 19:48:12 +02:00
parent 57aa8818a9
commit 8d640d0b79
5 changed files with 48 additions and 27 deletions

View file

@ -1,3 +1,4 @@
import { throttle } from 'lodash'
import { mapState, mapActions } from 'pinia'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import { v4 as uuidv4 } from 'uuid';
@ -40,7 +41,8 @@ const FilteringTab = {
)
},
methods: {
...mapActions(useServerSideStorageStore, ['setPreference', 'unsetPreference', 'pushServerSideStorage']),
...mapActions(useServerSideStorageStore, ['setPreference', 'unsetPreference']),
pushServerSideStorage: throttle(() => useServerSideStorageStore().pushServerSideStorage(), 500),
getDatetimeLocal (timestamp) {
const date = new Date(timestamp)
const datetime = [

View file

@ -14,7 +14,7 @@ import MentionLink from 'src/components/mention_link/mention_link.vue'
import StatusActionButtons from 'src/components/status_action_buttons/status_action_buttons.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 { muteWordHits } from '../../services/status_parser/status_parser.js'
import { muteFilterHits } from '../../services/status_parser/status_parser.js'
import { unescape, uniqBy } from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core'
@ -161,9 +161,6 @@ const Status = {
},
computed: {
...controlledOrUncontrolledGetters(['replying', 'mediaPlaying']),
muteWords () {
return this.mergedConfig.muteWords
},
showReasonMutedThread () {
return (
this.status.thread_muted ||
@ -221,8 +218,9 @@ const Status = {
loggedIn () {
return !!this.currentUser
},
muteWordHits () {
return muteWordHits(this.status, this.muteWords)
muteFilterHits () {
console.log(muteFilterHits(this.status))
return muteFilterHits(this.status)
},
botStatus () {
return this.status.user.actor_type === 'Service'
@ -256,7 +254,7 @@ const Status = {
return [
this.userIsMuted ? 'user' : null,
this.status.thread_muted ? 'thread' : null,
(this.muteWordHits.length > 0) ? 'wordfilter' : null,
(this.muteFilterHits.length > 0) ? 'filtered' : null,
(this.muteBotStatuses && this.botStatus) ? 'bot' : null,
(this.muteSensitiveStatuses && this.sensitiveStatus) ? 'nsfw' : null
].filter(_ => _)
@ -267,14 +265,14 @@ const Status = {
switch (this.muteReasons[0]) {
case 'user': return this.$t('status.muted_user')
case 'thread': return this.$t('status.thread_muted')
case 'wordfilter':
case 'filtered':
return this.$t(
'status.muted_words',
'status.muted_filters',
{
word: this.muteWordHits[0],
numWordsMore: this.muteWordHits.length - 1
name: this.muteFilterHits[0].name,
filterMore: this.muteFilterHits.length - 1
},
this.muteWordHits.length
this.muteFilterHits.length
)
case 'bot': return this.$t('status.bot_muted')
case 'nsfw': return this.$t('status.sensitive_muted')
@ -326,7 +324,7 @@ const Status = {
// 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
) && !this.muteFilterHits.length > 0
},
hideMutedUsers () {
return this.mergedConfig.hideMutedPosts
@ -345,7 +343,8 @@ const Status = {
(this.muted && this.hideFilteredStatuses) ||
(this.userIsMuted && this.hideMutedUsers) ||
(this.status.thread_muted && this.hideMutedThreads) ||
(this.muteWordHits.length > 0 && this.hideWordFilteredPosts)
(this.muteFilterHits.length > 0 && this.hideWordFilteredPosts) ||
(this.muteFilterHits[0]?.hide)
)
},
isFocused () {

View file

@ -1281,6 +1281,7 @@
"copy_link": "Copy link to status",
"external_source": "External source",
"muted_words": "Wordfiltered: {word} | Wordfiltered: {word} and {numWordsMore} more words",
"muted_filters": "Filtered: {name} | Wordfiltered: {name} and {filtersMore} more words",
"multi_reason_mute": "{main} + one more reason | {main} + {numReasonsMore} more reasons",
"muted_user": "User muted",
"thread_muted": "Thread muted",

View file

@ -1,4 +1,4 @@
import { muteWordHits } from '../status_parser/status_parser.js'
import { muteFilterHits } from '../status_parser/status_parser.js'
import { showDesktopNotification } from '../desktop_notification_utils/desktop_notification_utils.js'
import { useI18nStore } from 'src/stores/i18n.js'
import { useAnnouncementsStore } from 'src/stores/announcements'
@ -58,10 +58,10 @@ const sortById = (a, b) => {
}
}
const isMutedNotification = (store, notification) => {
if (!notification.status) return
const rootGetters = store.rootGetters || store.getters
return notification.status.muted || muteWordHits(notification.status, rootGetters.mergedConfig.muteWords).length > 0
const isMutedNotification = (notification) => {
if (!notification.status) return false
if (notification.status.muted) return true
return muteFilterHits(notification.status).length > 0
}
export const maybeShowNotification = (store, notification) => {
@ -69,7 +69,7 @@ export const maybeShowNotification = (store, notification) => {
if (notification.seen) return
if (!visibleTypes(store).includes(notification.type)) return
if (notification.type === 'mention' && isMutedNotification(store, notification)) return
if (notification.type === 'mention' && isMutedNotification(notification)) return
const notificationObject = prepareNotificationObject(notification, useI18nStore().i18n)
showDesktopNotification(rootState, notificationObject)

View file

@ -1,11 +1,30 @@
import { filter } from 'lodash'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
export const muteWordHits = (status, muteWords) => {
export const muteFilterHits = (status) => {
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
const muteFilters = Object.values(useServerSideStorageStore().prefsStorage.simple.muteFilters)
return muteFilters.toSorted((a,b) => b.order - a.order).map(filter => {
const { hide, expires, name, value, type} = filter
if (expires !== null && expires < Date.now()) return false
switch (type) {
case 'word': {
if (statusText.includes(value) || statusSummary.includes(value)) {
return { hide, name }
}
}
case 'regexp': {
try {
const re = new RegExp(value, 'i')
if (re.test(statusText) || re.test(statusSummary)) {
return { hide, name }
}
} catch {
return false
}
}
}
}).filter(_ => _)
}