tooot/src/components/Timeline/Shared/Filtered.tsx

118 lines
3.5 KiB
TypeScript
Raw Normal View History

import CustomText from '@components/Text'
2021-05-30 23:39:07 +02:00
import { store } from '@root/store'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
import { getInstance, getInstanceAccount } from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import htmlparser2 from 'htmlparser2-without-node-native'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { View } from 'react-native'
2021-05-30 23:39:07 +02:00
const TimelineFiltered = React.memo(
({ phrase }: { phrase: string }) => {
2022-02-12 14:51:01 +01:00
const { colors } = useTheme()
2021-05-30 23:39:07 +02:00
const { t } = useTranslation('componentTimeline')
return (
2022-02-12 14:51:01 +01:00
<View style={{ backgroundColor: colors.backgroundDefault }}>
<CustomText
fontStyle='S'
2021-05-30 23:39:07 +02:00
style={{
2022-02-12 14:51:01 +01:00
color: colors.secondary,
2021-05-30 23:39:07 +02:00
textAlign: 'center',
paddingVertical: StyleConstants.Spacing.S,
paddingLeft: StyleConstants.Avatar.M + StyleConstants.Spacing.S
}}
>
{t('shared.filtered', { phrase })}
</CustomText>
2021-05-30 23:39:07 +02:00
</View>
)
},
() => true
)
export const shouldFilter = ({
2022-08-09 00:44:56 +02:00
copiableContent,
2021-05-30 23:39:07 +02:00
status,
queryKey
}: {
2022-08-09 00:44:56 +02:00
copiableContent: React.MutableRefObject<{
content: string
complete: boolean
}>
2021-05-30 23:39:07 +02:00
status: Mastodon.Status
queryKey: QueryKeyTimeline
}): string | null => {
2021-05-30 23:39:07 +02:00
const instance = getInstance(store.getState())
const ownAccount = getInstanceAccount(store.getState())?.id === status.account?.id
2021-05-30 23:39:07 +02:00
let shouldFilter: string | null = null
2021-06-02 22:27:51 +02:00
if (!ownAccount) {
2021-05-30 23:39:07 +02:00
const parser = new htmlparser2.Parser({
2022-02-10 23:09:40 +01:00
ontext: (text: string) => {
2022-08-09 00:44:56 +02:00
if (!copiableContent.current.complete) {
copiableContent.current.content = copiableContent.current.content + text
2022-08-09 00:44:56 +02:00
}
2021-05-30 23:39:07 +02:00
const checkFilter = (filter: Mastodon.Filter) => {
const escapedPhrase = filter.phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
2021-05-30 23:39:07 +02:00
switch (filter.whole_word) {
case true:
2022-06-01 23:39:48 +02:00
if (new RegExp('\\b' + escapedPhrase + '\\b').test(text)) {
shouldFilter = filter.phrase
2021-05-30 23:39:07 +02:00
}
break
case false:
2021-06-02 22:27:51 +02:00
if (new RegExp(escapedPhrase).test(text)) {
shouldFilter = filter.phrase
2021-05-30 23:39:07 +02:00
}
break
}
}
2021-06-02 22:27:51 +02:00
instance?.filters?.forEach(filter => {
2021-05-30 23:39:07 +02:00
if (filter.expires_at) {
if (new Date().getTime() > new Date(filter.expires_at).getTime()) {
return
}
}
switch (queryKey[1].page) {
case 'Following':
case 'Local':
case 'List':
case 'Account_Default':
if (filter.context.includes('home')) {
checkFilter(filter)
}
break
case 'Notifications':
if (filter.context.includes('notifications')) {
checkFilter(filter)
}
break
case 'LocalPublic':
if (filter.context.includes('public')) {
checkFilter(filter)
}
break
case 'Toot':
if (filter.context.includes('thread')) {
checkFilter(filter)
}
}
})
}
})
2022-06-01 23:39:48 +02:00
status.spoiler_text && parser.write(status.spoiler_text)
2021-05-30 23:39:07 +02:00
parser.write(status.content)
parser.end()
2022-08-09 00:44:56 +02:00
copiableContent.current.complete = true
2021-05-30 23:39:07 +02:00
}
return shouldFilter
}
export default TimelineFiltered