add emoji reaction filtering
This commit is contained in:
parent
c43ddf6c7b
commit
7c275adfc8
10 changed files with 99 additions and 8 deletions
|
@ -19,6 +19,9 @@
|
||||||
- polls can now have up to 20 options instead of 4
|
- polls can now have up to 20 options instead of 4
|
||||||
- polls can now last anywhere from 1 second to 1000 years
|
- polls can now last anywhere from 1 second to 1000 years
|
||||||
- optional alternate gravestone when using websockets that still shows post content but removes buttons
|
- optional alternate gravestone when using websockets that still shows post content but removes buttons
|
||||||
|
- filters for reactions:
|
||||||
|
- matching by regex, domain-specific, or catch-all
|
||||||
|
- filters the actual reactions to post as well as notifications
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||||
import UserListPopover from '../user_list_popover/user_list_popover.vue'
|
import UserListPopover from '../user_list_popover/user_list_popover.vue'
|
||||||
import StillImage from '../still-image/still-image.vue'
|
import StillImage from '../still-image/still-image.vue'
|
||||||
|
|
||||||
|
import { toRaw } from 'vue'
|
||||||
|
|
||||||
const EMOJI_REACTION_COUNT_CUTOFF = 12
|
const EMOJI_REACTION_COUNT_CUTOFF = 12
|
||||||
|
|
||||||
const findEmojiByReplacement = (state, replacement) => {
|
const findEmojiByReplacement = (state, replacement) => {
|
||||||
|
@ -24,11 +26,6 @@ const EmojiReactions = {
|
||||||
tooManyReactions () {
|
tooManyReactions () {
|
||||||
return this.status.emoji_reactions.length > EMOJI_REACTION_COUNT_CUTOFF
|
return this.status.emoji_reactions.length > EMOJI_REACTION_COUNT_CUTOFF
|
||||||
},
|
},
|
||||||
emojiReactions () {
|
|
||||||
return this.showAll
|
|
||||||
? this.status.emoji_reactions
|
|
||||||
: this.status.emoji_reactions.slice(0, EMOJI_REACTION_COUNT_CUTOFF)
|
|
||||||
},
|
|
||||||
showMoreString () {
|
showMoreString () {
|
||||||
return `+${this.status.emoji_reactions.length - EMOJI_REACTION_COUNT_CUTOFF}`
|
return `+${this.status.emoji_reactions.length - EMOJI_REACTION_COUNT_CUTOFF}`
|
||||||
},
|
},
|
||||||
|
@ -44,9 +41,50 @@ const EmojiReactions = {
|
||||||
},
|
},
|
||||||
loggedIn () {
|
loggedIn () {
|
||||||
return !!this.$store.state.users.currentUser
|
return !!this.$store.state.users.currentUser
|
||||||
|
},
|
||||||
|
filteredReactions () {
|
||||||
|
// this is fucking Jank.
|
||||||
|
var finalReacts = this.emojiReactions()
|
||||||
|
var tempList = []
|
||||||
|
var reactionsFilterItems = this.$store.getters.mergedConfig.reactionsFilterItems.split("\n")
|
||||||
|
if (reactionsFilterItems.length > 0 && finalReacts.length > 0) {
|
||||||
|
reactionsFilterItems.forEach((item) => {
|
||||||
|
var toPush = []
|
||||||
|
finalReacts.forEach((react) => {
|
||||||
|
var rawReact = toRaw(react)["name"]
|
||||||
|
|
||||||
|
if (
|
||||||
|
// match regex
|
||||||
|
// >1 check is to prevent = just disabling all emoji reacts
|
||||||
|
item.charAt(0) == "=" && item.length > 1 && rawReact.match(item.substring(1))
|
||||||
|
// match everything explicit, if there's an @
|
||||||
|
|| rawReact == item.match(/.*@.*/) ? item : null
|
||||||
|
// match everything else
|
||||||
|
|| (rawReact.match(/.*@.*/) ? rawReact.split("@")[0] : rawReact) == item
|
||||||
|
) {
|
||||||
|
toPush.push(react)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
toPush.forEach((nice) => {
|
||||||
|
tempList.push(nice)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
tempList.forEach((item) => {
|
||||||
|
finalReacts.splice(finalReacts.indexOf(item), 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
return finalReacts
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
emojiReactions () {
|
||||||
|
return this.showAll
|
||||||
|
? this.status.emoji_reactions
|
||||||
|
: this.status.emoji_reactions.slice(0, EMOJI_REACTION_COUNT_CUTOFF)
|
||||||
|
},
|
||||||
toggleShowAll () {
|
toggleShowAll () {
|
||||||
this.showAll = !this.showAll
|
this.showAll = !this.showAll
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="emoji-reactions">
|
<div class="emoji-reactions">
|
||||||
<UserListPopover
|
<UserListPopover
|
||||||
v-for="(reaction) in emojiReactions"
|
v-for="(reaction) in filteredReactions"
|
||||||
:key="reaction.url || reaction.name"
|
:key="reaction.url || reaction.name"
|
||||||
:users="accountsForEmoji[reaction.url || reaction.name]"
|
:users="accountsForEmoji[reaction.url || reaction.name]"
|
||||||
>
|
>
|
||||||
|
|
|
@ -112,6 +112,33 @@ const Notification = {
|
||||||
this.$store.dispatch('removeFollowRequest', this.user)
|
this.$store.dispatch('removeFollowRequest', this.user)
|
||||||
})
|
})
|
||||||
this.hideDenyConfirmDialog()
|
this.hideDenyConfirmDialog()
|
||||||
|
},
|
||||||
|
filtered (emoji) {
|
||||||
|
var isFiltered = false
|
||||||
|
|
||||||
|
if (emoji.match(/.*:.*/)) {
|
||||||
|
emoji = emoji.replaceAll(":", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
var reactionsFilterItems = this.$store.getters.mergedConfig.reactionsFilterItems.split("\n")
|
||||||
|
|
||||||
|
if (reactionsFilterItems.length > 0)
|
||||||
|
reactionsFilterItems.forEach((item) => {
|
||||||
|
console.log(emoji)
|
||||||
|
if (
|
||||||
|
// match regex
|
||||||
|
// >1 check is to prevent = just disabling all emoji reacts
|
||||||
|
item.charAt(0) == "=" && item.length > 1 && emoji.match(item.substring(1))
|
||||||
|
// match everything explicit, if there's an @
|
||||||
|
|| emoji == item.match(/.*@.*/) ? item : null
|
||||||
|
// match everything else
|
||||||
|
|| (emoji.match(/.*@.*/) ? emoji.split("@")[0] : emoji) == item
|
||||||
|
) {
|
||||||
|
isFiltered = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return isFiltered
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
:compact="true"
|
:compact="true"
|
||||||
:statusoid="notification.status"
|
:statusoid="notification.status"
|
||||||
/>
|
/>
|
||||||
<div v-else>
|
<div v-else-if="(notification.emoji && !filtered(notification.emoji)) || !notification.emoji">
|
||||||
<div
|
<div
|
||||||
v-if="needMute && !unmuted"
|
v-if="needMute && !unmuted"
|
||||||
class="Notification container -muted"
|
class="Notification container -muted"
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { filter, trim, debounce } from 'lodash'
|
||||||
import BooleanSetting from '../helpers/boolean_setting.vue'
|
import BooleanSetting from '../helpers/boolean_setting.vue'
|
||||||
import ChoiceSetting from '../helpers/choice_setting.vue'
|
import ChoiceSetting from '../helpers/choice_setting.vue'
|
||||||
import IntegerSetting from '../helpers/integer_setting.vue'
|
import IntegerSetting from '../helpers/integer_setting.vue'
|
||||||
|
import TextSetting from '../helpers/text_setting.vue'
|
||||||
|
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
|
|
||||||
|
@ -19,7 +20,8 @@ const FilteringTab = {
|
||||||
components: {
|
components: {
|
||||||
BooleanSetting,
|
BooleanSetting,
|
||||||
ChoiceSetting,
|
ChoiceSetting,
|
||||||
IntegerSetting
|
IntegerSetting,
|
||||||
|
TextSetting
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...SharedComputedObject(),
|
...SharedComputedObject(),
|
||||||
|
|
|
@ -115,6 +115,23 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="setting-item"
|
||||||
|
>
|
||||||
|
<h2>{{ $t('settings.notification_setting_reactions') }}</h2>
|
||||||
|
<ul class="setting-list">
|
||||||
|
<li>
|
||||||
|
<h3>{{ $t('settings.reactions_filter') }}</h3>
|
||||||
|
<TextSetting
|
||||||
|
id="reactionsFilterItems"
|
||||||
|
path="reactionsFilterItems"
|
||||||
|
>
|
||||||
|
</TextSetting>
|
||||||
|
<!-- this is fucking stupid but for some reason the internationalization stuff (Not calling it i18n) hates this, so taking the liberty to also add styling -->
|
||||||
|
<div>Put reactions to remove in this box (formatted like reaction, no colons), one line for each. Results get matched like:<br><b><code>reaction</code></b> is a catch-all for all domains<br><b><code>reaction@domain.tld</code></b> is a reaction for a specific domain<br><b><code>=reaction</code></b> is a match via regex</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script src="./filtering_tab.js"></script>
|
<script src="./filtering_tab.js"></script>
|
||||||
|
|
|
@ -686,6 +686,7 @@
|
||||||
"notification_setting_hide_if_cw": "Hide the contents of push notifications if under a Content Warning",
|
"notification_setting_hide_if_cw": "Hide the contents of push notifications if under a Content Warning",
|
||||||
"notification_setting_hide_notification_contents": "Hide the sender and contents of push notifications",
|
"notification_setting_hide_notification_contents": "Hide the sender and contents of push notifications",
|
||||||
"notification_setting_privacy": "Privacy",
|
"notification_setting_privacy": "Privacy",
|
||||||
|
"notification_setting_reactions": "Reactions",
|
||||||
"notification_setting_sounds": "Sounds",
|
"notification_setting_sounds": "Sounds",
|
||||||
"notification_visibility": "Types of notifications to show",
|
"notification_visibility": "Types of notifications to show",
|
||||||
"notification_visibility_bites": "Bites",
|
"notification_visibility_bites": "Bites",
|
||||||
|
@ -719,6 +720,7 @@
|
||||||
},
|
},
|
||||||
"profile_tab": "Profile",
|
"profile_tab": "Profile",
|
||||||
"radii_help": "Set up interface edge rounding (in pixels)",
|
"radii_help": "Set up interface edge rounding (in pixels)",
|
||||||
|
"reactions_filter": "Filter reactions by name",
|
||||||
"recurse_search": "When searching, run searches until no results are found anymore",
|
"recurse_search": "When searching, run searches until no results are found anymore",
|
||||||
"recurse_search_limit": "Number of posts to stop recurse searching at (>300 will cause massive performance issues)",
|
"recurse_search_limit": "Number of posts to stop recurse searching at (>300 will cause massive performance issues)",
|
||||||
"refresh_token": "Refresh token",
|
"refresh_token": "Refresh token",
|
||||||
|
|
|
@ -124,6 +124,7 @@ export const defaultState = {
|
||||||
boostsFollowDefVis: false,
|
boostsFollowDefVis: false,
|
||||||
searchPaginationLimit: 40,
|
searchPaginationLimit: 40,
|
||||||
sillyFeatures: false,
|
sillyFeatures: false,
|
||||||
|
reactionsFilterItems: '',
|
||||||
recurseSearch: false,
|
recurseSearch: false,
|
||||||
recurseSearchLimit: 100,
|
recurseSearchLimit: 100,
|
||||||
renderMisskeyMarkdown: undefined,
|
renderMisskeyMarkdown: undefined,
|
||||||
|
|
|
@ -80,6 +80,7 @@ const defaultState = {
|
||||||
deletePostsStreaming: true,
|
deletePostsStreaming: true,
|
||||||
searchPaginationLimit: 40,
|
searchPaginationLimit: 40,
|
||||||
sillyFeatures: false,
|
sillyFeatures: false,
|
||||||
|
reactionsFilterItems: '',
|
||||||
recurseSearch: false,
|
recurseSearch: false,
|
||||||
recurseSearchLimit: 100,
|
recurseSearchLimit: 100,
|
||||||
renderMisskeyMarkdown: true,
|
renderMisskeyMarkdown: true,
|
||||||
|
|
Loading…
Add table
Reference in a new issue