feat: Added mixed adult account filter

This commit is contained in:
florian 2023-09-05 15:35:38 +02:00
parent 763e3b26f8
commit e3de2fdb7f
5 changed files with 55 additions and 19 deletions

View File

@ -5,10 +5,23 @@ import useNav from '../utils/useNav';
const AdultContentInfo = () => { const AdultContentInfo = () => {
const { nav, currentSettings } = useNav(); const { nav, currentSettings } = useNav();
/**
* Proceed function handles the event when the 'Proceed' button is clicked.
* It prevents the default button click action and navigates to the current settings with adult content enabled.
*
* @param {MouseEvent<HTMLButtonElement>} e - The event triggered by clicking the 'Proceed' button.
*/
const proceed = (e: MouseEvent<HTMLButtonElement>) => { const proceed = (e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault(); e.preventDefault();
nav({ ...currentSettings, showAdult: true }); nav({ ...currentSettings, showAdult: true });
}; };
/**
* GoBack function handles the event when the 'Go Back' button is clicked.
* It prevents the default button click action, resets the current settings and navigates back with adult content disabled.
*
* @param {MouseEvent<HTMLButtonElement>} e - The event triggered by clicking the 'Go Back' button.
*/
const goBack = (e: MouseEvent<HTMLButtonElement>) => { const goBack = (e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault(); e.preventDefault();
nav({ ...currentSettings, npubs: [], tags: [], showAdult: false }); nav({ ...currentSettings, npubs: [], tags: [], showAdult: false });

View File

@ -32,13 +32,24 @@ const SettingsDialog = ({ onClose }: SettingsProps) => {
const validNpubs = npubs.filter(t => t.length > 0); const validNpubs = npubs.filter(t => t.length > 0);
const validTags = selectedTags.filter(t => t.selected).map(t => t.name); const validTags = selectedTags.filter(t => t.selected).map(t => t.name);
// If the mode is 'user' and there is exactly one validNpubs
if (mode == 'user' && validNpubs.length == 1) { if (mode == 'user' && validNpubs.length == 1) {
// Navigate with the current settings, but only keep the validNpubs, and reset tags
nav({ ...currentSettings, tags: [], npubs: validNpubs, showAdult, showReplies, showReposts }); nav({ ...currentSettings, tags: [], npubs: validNpubs, showAdult, showReplies, showReposts });
} else if (mode == 'tags' && validTags.length > 0) { }
// If the mode is 'tags' and there is at least one valid tag
else if (mode == 'tags' && validTags.length > 0) {
// Navigate with the current settings, but only keep the validTags, and reset npubs
nav({ ...currentSettings, tags: validTags, npubs: [], showAdult, showReplies, showReposts }); nav({ ...currentSettings, tags: validTags, npubs: [], showAdult, showReplies, showReposts });
} else if (mode == 'tags') { }
// If the mode is 'tags' but there are no valid tags
else if (mode == 'tags') {
// Navigate with the current settings, but reset npubs and use defaultHashTags as tags
nav({ ...currentSettings, tags: defaultHashTags, npubs: [], showAdult, showReplies, showReposts }); nav({ ...currentSettings, tags: defaultHashTags, npubs: [], showAdult, showReplies, showReposts });
} else { }
// If none of the above conditions are met
else {
// Navigate with the current settings, but reset both tags and npubs
nav({ ...currentSettings, tags: [], npubs: [], showAdult, showReplies, showReposts }); nav({ ...currentSettings, tags: [], npubs: [], showAdult, showReplies, showReposts });
} }

View File

@ -12,7 +12,7 @@ import {
prepareContent, prepareContent,
Post, Post,
} from './nostrImageDownload'; } from './nostrImageDownload';
import { blockedPublicKeys, adultContentTags, adultNPubs } from './env'; import { blockedPublicKeys, adultContentTags, adultNPubs, mixedAdultNPubs } from './env';
import Settings from './Settings'; import Settings from './Settings';
import SlideView from './SlideView'; import SlideView from './SlideView';
import GridView from './GridView'; import GridView from './GridView';
@ -109,7 +109,7 @@ const SlideShow = () => {
!blockedPublicKeys.includes(event.pubkey.toLowerCase()) && // remove blocked authors !blockedPublicKeys.includes(event.pubkey.toLowerCase()) && // remove blocked authors
(settings.showReplies || !isReply(event)) && (settings.showReplies || !isReply(event)) &&
oldPosts.findIndex(p => p.event.id === event.id) === -1 && // not duplicate oldPosts.findIndex(p => p.event.id === event.id) === -1 && // not duplicate
(settings.showAdult || !isAdultRelated(event)) (settings.showAdult || !isAdultRelated(event, settings.tags.length > 0))
) { ) {
return [...oldPosts, { event }]; return [...oldPosts, { event }];
} }
@ -160,11 +160,10 @@ const SlideShow = () => {
const onKeyDown = (event: KeyboardEvent) => { const onKeyDown = (event: KeyboardEvent) => {
if (showSettings) return; if (showSettings) return;
if (event.key.toLowerCase() === 'g') {
if (event.key === 'g' || event.key === 'G') {
setShowGrid(p => !p); setShowGrid(p => !p);
} }
if (event.key === 's' || event.key === 'S') { if (event.key.toLowerCase() === 's') {
setShowSettings(s => !s); setShowSettings(s => !s);
} }
if (event.key === 'Escape') { if (event.key === 'Escape') {
@ -195,7 +194,7 @@ const SlideShow = () => {
const showAdultContentWarning = const showAdultContentWarning =
!settings.showAdult && !settings.showAdult &&
(adultContentTags.some(t => settings.tags.includes(t)) || adultNPubs.some(p => settings.npubs.includes(p))); (adultContentTags.some(t => settings.tags.includes(t)) || adultNPubs.some(p => settings.npubs.includes(p)) || mixedAdultNPubs.some(p => settings.npubs.includes(p)));
if (showAdultContentWarning) { if (showAdultContentWarning) {
return <AdultContentInfo></AdultContentInfo>; return <AdultContentInfo></AdultContentInfo>;

View File

@ -93,18 +93,23 @@ export const adultContentTags = [
'sex', 'sex',
'suicidegirls', 'suicidegirls',
'thighstr', 'thighstr',
'teenstr',
'tits', 'tits',
'titstr', 'titstr',
'xxx', 'xxx',
'nostrqueen'
]; ];
export const mixedAdultNPubs = [
'npub12jedfuhk2wfr7syr38t2f55652khuyz9f88r63ftm0j2vudxq9sqq7677r', // Erikha
]
/* These profiles are flagged as adult / NSFW and their content is not shown /* These profiles are flagged as adult / NSFW and their content is not shown
by default. Users can enable their content through the adult content flag by default. Users can enable their content through the adult content flag
in the UI or through a URL parameter. in the UI or through a URL parameter.
*/ */
export const adultNPubs = [ export const adultNPubs = [
'npub10m75ad8pc6wtlt67f6wjeug4hpqurc68842ve5ne47u9lkjqa0lq8ja88s', // 313Chris:hellokitty_headbang: 'npub10m75ad8pc6wtlt67f6wjeug4hpqurc68842ve5ne47u9lkjqa0lq8ja88s', // 313Chris:hellokitty_headbang:
'npub12jedfuhk2wfr7syr38t2f55652khuyz9f88r63ftm0j2vudxq9sqq7677r', // Erikha
'npub13806pd9p833wkgyemeqddjzdksunlq9gszq4yjnhw4l57sjjhwlq6m79nj', // Orvalho 'npub13806pd9p833wkgyemeqddjzdksunlq9gszq4yjnhw4l57sjjhwlq6m79nj', // Orvalho
'npub13n6ednsew67xk7hgse670z7849q5h8su5rgydxtl4lq3r5cx4ecqsd9af4', // Everybody, Every Body 'npub13n6ednsew67xk7hgse670z7849q5h8su5rgydxtl4lq3r5cx4ecqsd9af4', // Everybody, Every Body
'npub16932qv3sz53t9fdlm2n7scct5ahe9fy9vsct36qd0wcwxm94gyks47dcg6', // Preggers 'npub16932qv3sz53t9fdlm2n7scct5ahe9fy9vsct36qd0wcwxm94gyks47dcg6', // Preggers
@ -159,6 +164,8 @@ export const adultNPubs = [
'npub1ylrnf0xfp9wsmqthxlqjqyqj9yy27pnchjwjq93v3mq66ts7ftjs6x7dcq', // Welcome To The Jungle 'npub1ylrnf0xfp9wsmqthxlqjqyqj9yy27pnchjwjq93v3mq66ts7ftjs6x7dcq', // Welcome To The Jungle
'npub1z0xv9t5w6evrcg860kmgqq5tfj55mz84ta40uszjnfp9uhw2clkq63yrak', // ??? 'npub1z0xv9t5w6evrcg860kmgqq5tfj55mz84ta40uszjnfp9uhw2clkq63yrak', // ???
'npub1sg7rwnf96a0fhl85xlvq0unumqqh89qaygwcdy5d3ue8209ekt2suhxg7u', // Anime Mommies Bot 'npub1sg7rwnf96a0fhl85xlvq0unumqqh89qaygwcdy5d3ue8209ekt2suhxg7u', // Anime Mommies Bot
'npub1kq67ngznkldmecycjfmjt4deuvyxgpn4zcpq8cvfmdl2hufzzccs6nc9q8', // Sargas
'npub10y6rhnutt52wwt5f7544tq4as6jt03aq7j8mle7wcymjjudanm4q4hvzaw', // NSFW
'npub1t07mr7m65lg3ecr5eapu6qe4ayt2wgjpqjs8x58m5kx2r2cutsyqyzzzs9', // NOT NSFW but spammy ai pictures 'npub1t07mr7m65lg3ecr5eapu6qe4ayt2wgjpqjs8x58m5kx2r2cutsyqyzzzs9', // NOT NSFW but spammy ai pictures
'npub1curnt7jtq8mhl9fcswnwvuvc9ccm6lvsdv4kzydx75v92kldrvdqh7sq09', // NOT NSFW but spammy ai pictures 'npub1curnt7jtq8mhl9fcswnwvuvc9ccm6lvsdv4kzydx75v92kldrvdqh7sq09', // NOT NSFW but spammy ai pictures
@ -166,6 +173,8 @@ export const adultNPubs = [
export const adultPublicKeys = adultNPubs.map(npub => (nip19.decode(npub).data as string).toLowerCase()); export 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());
/* The following profiles have questionable content and are blocked completely on slidestr.net */ /* The following profiles have questionable content and are blocked completely on slidestr.net */
export const blockedNPubs = [ export const blockedNPubs = [
'npub1awxh85c5wasj60d42uvmzuza2uvjazff9m7skg2vf7x2f8gykwkqykxktf', // AIイラスト', 'npub1awxh85c5wasj60d42uvmzuza2uvjazff9m7skg2vf7x2f8gykwkqykxktf', // AIイラスト',

View File

@ -1,6 +1,6 @@
import { NDKEvent, NDKFilter, NDKTag } from '@nostr-dev-kit/ndk'; import { NDKEvent, NDKFilter, NDKTag } from '@nostr-dev-kit/ndk';
import { Kind, nip19 } from 'nostr-tools'; import { Kind, nip19 } from 'nostr-tools';
import { adultContentTags, adultPublicKeys } from './env'; import { adultContentTags, adultPublicKeys, mixedAdultNPubs } from './env';
export type Post = { export type Post = {
event: NDKEvent; event: NDKEvent;
@ -78,22 +78,26 @@ export const hasAdultTag = ({ tags }: { tags?: NDKTag[] }) => {
return tags.filter((t: string[]) => t[0] === 't' && adultContentTags.includes(t[1])).length > 0; return tags.filter((t: string[]) => t[0] === 't' && adultContentTags.includes(t[1])).length > 0;
}; };
export const isAdultRelated = ({ tags, pubkey }: { tags?: NDKTag[]; pubkey: string }) => { 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 })) {
return false;
}
return ( return (
hasContentWarning({ tags }) || // block content warning hasContentWarning({ tags }) || // block content warning
hasAdultTag({ tags }) || // block adult tags hasAdultTag({ tags }) || // block adult tags
mixedAdultNPubs.includes(pubkey.toLowerCase()) || // block mixed adult authors
adultPublicKeys.includes(pubkey.toLowerCase()) // block adult authors adultPublicKeys.includes(pubkey.toLowerCase()) // block adult authors
); );
}; };
export const isImage = (url: string) => { export const isImage = (url: string) => {
return ( const fileExtension = url.split('.').pop();
url.endsWith('.jpg') || if (fileExtension == undefined) return false;
url.endsWith('.png') || const imageExtensions = ['jpg', 'png', 'gif', 'jpeg', 'webp'];
url.endsWith('.gif') || return imageExtensions.includes(fileExtension);
url.endsWith('.jpeg') ||
url.endsWith('.webp')
);
}; };
export const isVideo = (url: string) => { export const isVideo = (url: string) => {