chore: Optimized some code for adult checks

This commit is contained in:
florian 2024-09-08 11:44:55 +02:00
parent e55c16077b
commit b4a657cc25
8 changed files with 79 additions and 28 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 KiB

View File

@ -2,7 +2,7 @@ import { useEffect } from 'react';
import { NostrImage, urlFix } from '../nostrImageDownload';
import './GridView.css';
import GridImage from './GridImage';
import { Settings } from '../../utils/useNav';
import useNav, { Settings } from '../../utils/useNav';
import AuthorProfile from '../AuthorProfile/AuthorProfile';
import { useSwipeable } from 'react-swipeable';
import { Helmet } from 'react-helmet';
@ -26,6 +26,7 @@ const GridView = ({ settings, images, currentImage, setCurrentImage, setViewMode
const showNextImage = () => {
setCurrentImage(idx => (idx !== undefined ? idx + 1 : 0));
};
const { nav, currentSettings } = useNav();
const showPreviousImage = () => {
setCurrentImage(idx => (idx !== undefined && idx > 0 ? idx - 1 : idx));
@ -38,11 +39,15 @@ const GridView = ({ settings, images, currentImage, setCurrentImage, setViewMode
if (event.key === 'ArrowLeft') {
showPreviousImage();
}
/*
if (event.key === 'Escape') {
setCurrentImage(undefined);
nav({
...currentSettings,
topic: undefined,
npubs: [],
tags: [],
list: undefined,
});
}
*/
};
const swipeHandlers = useSwipeable({

View File

@ -40,7 +40,12 @@ const MasonryImage = ({ image, onClick, index }: MasonryImageProps) => {
const showAuthor = currentSettings.npubs == undefined || currentSettings.npubs.length != 1; // if we are looking at a single profile, don't show the author
const description = image.content && image.content?.substring(0, 60) + (image.content.length > 60 ? ' ... ' : ' ');
const description = useMemo(
() =>
image.content &&
image.content.replace(/nostr:[a-z0-9]+/, '').substring(0, 60) + (image.content.length > 60 ? ' ... ' : ' '),
[image.content]
);
const showTags = useMemo(() => uniq(image.tags).slice(0, 5), [image.tags]);
const now = unixNow();
const showInfo = true;

View File

@ -80,11 +80,9 @@ const MasonryView = ({ settings, images, currentImage, setCurrentImage, setViewM
if (event.key === 'ArrowLeft') {
showPreviousImage();
}
/*
if (event.key === 'Escape') {
setCurrentImage(undefined);
}
*/
};
const swipeHandlers = useSwipeable({

View File

@ -10,8 +10,9 @@ import {
Post,
isReply,
isAdultRelated,
hasBlockedTag,
} from './nostrImageDownload';
import { adultContentTags, adultNPubs, blockedPublicKeys, mixedAdultNPubs, topics } from './env';
import { adultContentTagsMap, adultNPubs, blockedPublicKeysMap, mixedAdultNPubs, topics } from './env';
import Settings from './Settings';
import SlideView from './SlideView';
import { nip19 } from 'nostr-tools';
@ -135,7 +136,8 @@ const SlideShow = () => {
events
.filter(
event =>
!blockedPublicKeys.includes(event.pubkey.toLowerCase()) && // remove blocked authors
!blockedPublicKeysMap[event.pubkey.toLowerCase()] && // remove blocked authors
!hasBlockedTag(event) &&
(settings.showReplies || !isReply(event)) &&
(settings.showAdult || !isAdultRelated(event, settings.tags.length > 0))
)
@ -309,10 +311,9 @@ const SlideShow = () => {
const fullScreen = document.fullscreenElement !== null;
const showAdultContentWarning =
!settings.showAdult &&
(adultContentTags.some(t => settings.tags.includes(t)) ||
adultNPubs.some(p => settings.npubs.includes(p)) ||
mixedAdultNPubs.some(p => settings.npubs.includes(p)));
!settings.showAdult && (settings.tags.some(t => adultContentTagsMap[t]) ||
adultNPubs.some(p => settings.npubs.includes(p)) ||
mixedAdultNPubs.some(p => settings.npubs.includes(p)));
if (showAdultContentWarning) {
return <AdultContentInfo></AdultContentInfo>;

View File

@ -17,7 +17,7 @@ type Topic = {
by default. Users can enable this content through the adult content flag
in the UI or through a URL parameter.
*/
export const adultContentTags = [
const adultContentTags = [
'adult',
'ass',
'blowjob',
@ -63,11 +63,15 @@ export const adultContentTags = [
'masturbation',
];
export const topics: { [key: string]: Topic } = {
nostriga: {
name: 'Baltic Honey Badger 2024 / NOSTRIGA',
tags: ['nostriga', 'balticbadger', 'honeybadger', 'riga', 'bh2024', 'hb2024'],
export const adultContentTagsMap = adultContentTags.reduce(
(acc, tag) => {
acc[tag.toLocaleLowerCase()] = true;
return acc;
},
{} as Record<string, boolean>
);
export const topics: { [key: string]: Topic } = {
art: {
name: 'Art',
tags: [
@ -199,9 +203,13 @@ export const topics: { [key: string]: Topic } = {
},
btcprague: {
name: 'BTC Prague',
tags: ['btcprague', 'BTCPrague', 'devhackday', 'prague', 'praha'],
tags: ['btcprague', 'BTCPrague', 'devhackday'],
description: 'All images/videos with related hashtags #btcprague #prague #praha',
},
bh2024nostriga: {
name: 'Baltic Honey Badger 2024 / NOSTRIGA',
tags: ['nostriga', 'balticbadger', 'honeybadger', 'riga', 'bh2024', 'hb2024'],
},
nsfw: {
name: 'NSFW / Adult Content',
tags: adultContentTags,
@ -381,14 +389,32 @@ export const adultNPubs = [
'npub1rxsxj8egpr3emylfdld0wgh63w048tjh5zaua84h2qjscswn68ysdlt68s',
'npub13lpdphw06d5hy5h7n0xsun9sfpwqsna9gsg0y0d4ukktks048nrseedtx9',
'npub1lrxxjtq7zyp2d4n44tllwqj4q20kk7dslh2xrq0qkwng5lldxqesmvvgyt',
'npub163nprvuh3y36l7we66hs6jhl92xymlnyq29mh3p86upe2828x7mqt8xdwf',
'npub16fsxfvylsvlmv9fz3k7rga3wxl50plm8q708wgkwdr555lczlc5qu7xw8z',
];
export const adultPublicKeys = adultNPubs.map(npub => (nip19.decode(npub).data as string).toLowerCase());
const adultPublicKeys = adultNPubs.map(npub => (nip19.decode(npub).data as string).toLowerCase());
export const mixedAdultPublicKeys = mixedAdultNPubs.map(npub => (nip19.decode(npub).data as string).toLowerCase());
export const adultPublicKeysMap = adultPublicKeys.reduce(
(acc, key) => {
acc[key.toLocaleLowerCase()] = true;
return acc;
},
{} as Record<string, boolean>
);
const mixedAdultPublicKeys = mixedAdultNPubs.map(npub => (nip19.decode(npub).data as string).toLowerCase());
export const mixedAdultPublicMaps = mixedAdultPublicKeys.reduce(
(acc, key) => {
acc[key.toLocaleLowerCase()] = true;
return acc;
},
{} as Record<string, boolean>
);
/* The following profiles have questionable content and are blocked completely on slidestr.net */
export const blockedNPubs = [
const blockedNPubs = [
'npub10m6d9ynzzx0w07spu2n5cx36z77smmyn7rs9gsvta57etrcyh68swace67',
'npub10xrnm6sy804cakmeew4g7kd4fl3dfvvsqfk6m3v4c6j4smrh9mlsdwpz7a', // CISAM
'npub125wcpwdn0zmt3accu3jlkv349jgw9d8htk4cjx2spc9qfvusl7hs6np5pt',
@ -415,9 +441,20 @@ export const blockedNPubs = [
'npub1tt3n7nm548jf4jsgy9vwt25khz2n47d8um0lam0nmpk034zzlp2sfpc7tq',
'npub1yrqtnr4qxvjqj4zs45sw3xlrflzks86dhy0y4hzj9jweujflksfszhsp06',
'npub13mnfsm49p8hka246khma4gdzd9w8ygyt3udrcxmgmmhd5cyt5y3q879pvy',
'npub13yn69pulpr6clwpzfj06rshu7kzj7zqvhf7d3mkyppynzrlnjjzqgsma3m',
];
export const blockedPublicKeys = blockedNPubs.map(npub => (nip19.decode(npub).data as string).toLowerCase());
const blockedPublicKeys = blockedNPubs.map(npub => (nip19.decode(npub).data as string).toLowerCase());
export const blockedPublicKeysMap = blockedPublicKeys.reduce(
(acc, key) => {
acc[key] = true;
return acc;
},
{} as Record<string, boolean>
);
export const blockedHashtags = ['loli'];
export const spamAccounts = [];

View File

@ -1,5 +1,5 @@
import { NDKEvent, NDKFilter, NDKTag } from '@nostr-dev-kit/ndk';
import { adultContentTags, adultPublicKeys, imageProxy, mixedAdultNPubs } from './env';
import { adultContentTagsMap, adultPublicKeysMap, blockedHashtags, imageProxy, mixedAdultPublicMaps } from './env';
import uniq from 'lodash/uniq';
import { unixNow } from '../ngine/time';
import { ContentType } from '../utils/useNav';
@ -94,21 +94,26 @@ export const hasContentWarning = ({ tags }: { tags?: NDKTag[] }) => {
export const hasAdultTag = ({ tags }: { tags?: NDKTag[] }) => {
if (!tags) return false;
// ["e", "aab5a68f29d76a04ad79fe7e489087b802ee0f946689d73b0e15931dd40a7af3", "", "reply"]
return tags.filter((t: string[]) => t[0] === 't' && adultContentTags.includes(t[1])).length > 0;
return tags.some((t: string[]) => t[0] === 't' && adultContentTagsMap[t[1]]);
};
export const hasBlockedTag = ({ tags }: { tags?: NDKTag[] }) => {
if (!tags) return false;
return tags.filter((t: string[]) => t[0] === 't' && blockedHashtags.includes(t[1])).length > 0;
};
export const isAdultRelated = ({ tags, pubkey }: { tags?: NDKTag[]; pubkey: string }, isTagSearch: boolean) => {
// if we search for a specific non adult tag and the user in the mixed category
// allow as non adult
if (isTagSearch && mixedAdultNPubs.includes(pubkey.toLowerCase()) && !hasAdultTag({ tags })) {
if (isTagSearch && mixedAdultPublicMaps[pubkey.toLowerCase()] && !hasAdultTag({ tags })) {
return false;
}
return (
hasContentWarning({ tags }) || // block content warning
hasAdultTag({ tags }) || // block adult tags
mixedAdultNPubs.includes(pubkey.toLowerCase()) || // block mixed adult authors
adultPublicKeys.includes(pubkey.toLowerCase()) // block adult authors
mixedAdultPublicMaps[pubkey.toLowerCase()] || // block mixed adult authors
adultPublicKeysMap[pubkey.toLowerCase()] // block adult authors
);
};