feat: Added better nsfw filtering

This commit is contained in:
florian 2023-07-21 16:27:48 +02:00
parent d6ee3d4270
commit b26ff70f52
3 changed files with 83 additions and 19 deletions

View File

@ -11,11 +11,12 @@ import {
buildFilter,
extractImageUrls,
hasContentWarning,
hasNsfwTag,
isReply,
prepareContent,
urlFix,
} from "./nostrImageDownload";
import { appName } from "./env";
import { appName, nsfwPubKeys } from "./env";
/*
FEATURES:
@ -39,6 +40,7 @@ FEATURES:
- Prevent duplicates (shuffle?), prevent same author twice in a row
- show content warning?
- Support Deleted Events
- Prevent duplicate images (shuffle? histroy?)
*/
let oldest = Infinity;
@ -55,6 +57,8 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => {
const [posts, setPosts] = useState<any[]>([]);
const images = useRef<NostrImage[]>([]);
const [activeImages, setActiveImages] = useState<NostrImage[]>([]);
const [history, setHistory] = useState<NostrImage[]>([]);
const upcommingImage = useRef<NostrImage>();
const [title, setTitle] = useState(appName);
const [paused, setPaused] = useState(false);
@ -88,6 +92,8 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => {
if (
!isReply(event) &&
(npub !== undefined || !hasContentWarning(event)) && // only allow content warnings on profile content
(npub !== undefined || !hasNsfwTag(event)) && // only allow nsfw on profile content
(npub !== undefined || !nsfwPubKeys.includes(event.pubkey.toLowerCase()) ) && // block nsfw authors
oldPosts.findIndex((p) => p.id === event.id) === -1
) {
return [...oldPosts, event];
@ -113,28 +119,34 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => {
};
useEffect(() => {
loadNdk([
"wss://relay.nostr.band",
"wss://nos.lol",
"wss://relay.mostr.pub",
"wss://purplepag.es/", // needed for user profiles
//"wss://feeds.nostr.band/pics"
]);
fetch();
}, []);
const animateImages = () => {
setActiveImages((oldImages) => {
const newImages = [...oldImages];
if (newImages.length > 2) {
const newActiveImages = [...oldImages];
if (newActiveImages.length > 2) {
// always keep 2 images
newImages.shift();
newActiveImages.shift();
}
if (images.current.length > 0) {
const randomImage =
images.current[Math.floor(Math.random() * images.current.length)];
newImages.push(randomImage);
images.current = images.current.filter((i) => i !== randomImage);
setHistory((oldHistory) => [...oldHistory, randomImage]);
newActiveImages.push(randomImage);
upcommingImage.current = randomImage;
}
return newImages;
return newActiveImages;
});
};
@ -150,8 +162,9 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => {
)
.map((url) => ({
url,
author: p.author,
author: p.author.npub,
content: prepareContent(p.content),
tags: p.tags.filter((t: string[]) => t[0] === "t").map((t: string[]) => t[1].toLowerCase()),
}));
});
console.log(images.current.length);
@ -174,6 +187,10 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => {
}
};
useEffect(() => {
console.log(history);
}, [history]);
const queueNextImage = (waitTime = 8000) => {
clearTimeout(timeoutHandle.current);
timeoutHandle.current = setTimeout(() => {
@ -197,7 +214,7 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => {
useDebouncedEffect(
() => {
setActiveNpub(upcommingImage?.current?.author?.npub);
setActiveNpub(upcommingImage?.current?.author);
setActiveContent(upcommingImage?.current?.content);
},
[upcommingImage?.current],

View File

@ -1,11 +1,49 @@
import { nip19 } from "nostr-tools";
export const appName = "slidestr.net";
export const defaultHashTags = [
"photography",
"photostr",
"artstr",
"art",
"catstr",
"dogstr",
"nature",
];
"photography",
"photostr",
"artstr",
"art",
"catstr",
"dogstr",
"nature",
"naturephotography",
"streetphotography",
];
export const nfswTags = [
"nsfw",
"boobstr",
"titstr",
"nasstr",
"nudeart",
"pornstr",
"nude",
];
export const nsfwPubKeys = [
"npub1xfu7047thly6aghl79z97kckkvwfvtcx88n6wq7c2tlng484d8xqv0kuvv", // Erandis Vol
"npub1rv08kght99a7xwckm0qpmzw09m5gwppequgqd8lwu74eakgaavwsp5cjtw", // CuratedNSFW
"npub1femd0mrawr0jmtjr2jwa2nm90haxrpglzdt6tt0djrsav39e53asf74aer", // FemDom Raw
"npub19xwjw7f23nsmnsd0j72mvhrdswt4cp6urc5el2zuu8se3yfu87ess524je", // Gone Wild (NSFW)
"npub1ylrnf0xfp9wsmqthxlqjqyqj9yy27pnchjwjq93v3mq66ts7ftjs6x7dcq", // Welcome To The Jungle
"npub1ga79p6qsjh0xd343q3du2unf2gl6gk0rde36c06mafxkrssmnnesxyzcss", // Orange Incest 🔞
"npub1jjtzhxzu8dlf7yn480sz67tesnfl7gpzfpkgpez05d2z9y3lya5sxvky0y", // Selfie Girls
"npub1ve4ztpqvlgu3v6hgrvc4lrdl2ernue7lq2h8tcgaksrkxlm7gnsqkjmz4e", // bluntkaraoke
"npub1kul999wnt8gwa6l2vyuewhnmmp25gq7dly9zmgsw52x8csmqjgts7278rx", // 𝓟𝓮𝓽𝓲𝓽𝓮 𝓟𝓻𝓲𝓷𝓬𝓮𝓼𝓼
"npub1ulafm4d3n7ukl7yzg4hfnhfjut74nym5p83e3d67l3j62yc6ysqqrancw2", // naked
"npub13806pd9p833wkgyemeqddjzdksunlq9gszq4yjnhw4l57sjjhwlq6m79nj", // Orvalho
"npub1pl0qa9x3n8wt55em0x3zwuy02rtl5t3jsretr0egjqgkx2f6jztqt0xwew", // nude
"npub1af9lxfzeq5rxmu9zz7d85tn2ex8zvvlx0duqcemcdhkz9cvlt29st3rcgd", // Happy Nut
"npub1mgusda7ujnyuhhudwkyrp763k4dd9xspktekl0tg5v0j76yph8ssyrfdpm", // anisyia
"npub1jge7z2kpmpdra6g58vg95uznve8ctcenmlyp9ntr3kjymscyuqpqty2cdh", // Storm
"npub1y77j6jm5hw34xl5m85aumltv88arh2s7q383allkpfe4muarzc5qzfgru0", // sexy-models
"npub1jp9v034z3a26cp5hajwyuzl0hety5akdpwdnjaqgfd7pm2ts4dwsc29va8", // curatedbliss
"npub1e4n8nah09he25slv00dz3kav3jsu5jvp83aya234ejumcmu2xseqwrp6pl", // Svenno(NSFW)
"npub1suddec4n2jv50pgn9eea35r4k83ahr4mcj0zv2uec36w6jeuwagq82xjgl" // quiet.enjoyer
].map((npub) => (nip19.decode(npub).data as string).toLowerCase());
export const spamAccounts = [];

View File

@ -1,10 +1,11 @@
import { NDKFilter, NDKUser } from "@nostr-dev-kit/ndk";
import { NDKFilter } from "@nostr-dev-kit/ndk";
import { nip19 } from "nostr-tools";
import { appName, defaultHashTags } from "./env";
import { appName, defaultHashTags, nfswTags } from "./env";
export type NostrImage = {
url: string;
author: NDKUser;
author: string;
tags: string[];
content?: string;
};
@ -66,3 +67,11 @@ export const hasContentWarning = (event: any) => {
event.tags.filter((t: string[]) => t[0] === "content-warning").length > 0
);
};
export const hasNsfwTag = (event: any) => {
// ["e", "aab5a68f29d76a04ad79fe7e489087b802ee0f946689d73b0e15931dd40a7af3", "", "reply"]
return (
event.tags.filter((t: string[]) => t[0] === "t" && nfswTags.includes(t[1]))
.length > 0
);
};