feat: Added AI Art topic
This commit is contained in:
parent
cb17cead0f
commit
9c2388c2b1
3
TODO.md
3
TODO.md
@ -1,6 +1,7 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
- use noteID as URL?
|
||||||
- add load more, to load older events
|
- add load more, to load older events
|
||||||
- Fix/Test zaps
|
- Fix Zaps, when not using a alby
|
||||||
- Reimplement Likes/Zaps based in ngine code
|
- Reimplement Likes/Zaps based in ngine code
|
||||||
- move settings dialog to main start screen
|
- move settings dialog to main start screen
|
||||||
- replace search icon with nav back button
|
- replace search icon with nav back button
|
||||||
|
BIN
public/images/aiart.jpg
Normal file
BIN
public/images/aiart.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 487 KiB |
BIN
public/images/nsfw.jpg
Normal file
BIN
public/images/nsfw.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
BIN
public/images/travel.jpg
Normal file
BIN
public/images/travel.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 526 KiB |
@ -19,7 +19,7 @@ const GridImage = ({ image, onClick, index }: GridImageProps) => {
|
|||||||
{mediaIsVideo ? (
|
{mediaIsVideo ? (
|
||||||
<video
|
<video
|
||||||
className={`image ${loaded ? 'show' : ''}`}
|
className={`image ${loaded ? 'show' : ''}`}
|
||||||
data-node-id={image.noteId}
|
data-node-id={image.post.event.id}
|
||||||
key={image.url}
|
key={image.url}
|
||||||
controls={false}
|
controls={false}
|
||||||
autoPlay={false}
|
autoPlay={false}
|
||||||
@ -31,7 +31,7 @@ const GridImage = ({ image, onClick, index }: GridImageProps) => {
|
|||||||
) : (
|
) : (
|
||||||
<img
|
<img
|
||||||
referrerPolicy="no-referrer"
|
referrerPolicy="no-referrer"
|
||||||
data-node-id={image.noteId}
|
data-node-id={image.post.event.id}
|
||||||
onError={(e: SyntheticEvent<HTMLImageElement>) => {
|
onError={(e: SyntheticEvent<HTMLImageElement>) => {
|
||||||
console.log('not found: ', e.currentTarget.src);
|
console.log('not found: ', e.currentTarget.src);
|
||||||
e.currentTarget.src = '/notfound.png';
|
e.currentTarget.src = '/notfound.png';
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
.home .topics {
|
.home .topics {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home .topic {
|
.home .topic {
|
||||||
@ -23,8 +23,9 @@
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 6em;
|
height: 7em;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home .topic-title {
|
.home .topic-title {
|
||||||
|
@ -3,7 +3,7 @@ import useNav from '../../utils/useNav';
|
|||||||
import './Home.css';
|
import './Home.css';
|
||||||
import usePeopleLists from '../../utils/useLists';
|
import usePeopleLists from '../../utils/useLists';
|
||||||
import { createImgProxyUrl } from '../nostrImageDownload';
|
import { createImgProxyUrl } from '../nostrImageDownload';
|
||||||
import { useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import useActiveProfile from '../../utils/useActiveProfile';
|
import useActiveProfile from '../../utils/useActiveProfile';
|
||||||
import useTitle from '../../utils/useTitle';
|
import useTitle from '../../utils/useTitle';
|
||||||
@ -16,7 +16,7 @@ const Home = () => {
|
|||||||
const { activeProfile } = useActiveProfile(currentSettings);
|
const { activeProfile } = useActiveProfile(currentSettings);
|
||||||
const title = useTitle(currentSettings, activeProfile);
|
const title = useTitle(currentSettings, activeProfile);
|
||||||
const [showAdult, setShowAdult] = useState(currentSettings.showAdult || false);
|
const [showAdult, setShowAdult] = useState(currentSettings.showAdult || false);
|
||||||
const topicKeys = Object.keys(topics);
|
const topicKeys = useMemo(() => Object.keys(topics).filter(tk => !topics[tk].nsfw || showAdult), [showAdult]);
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const lists = usePeopleLists(session?.pubkey);
|
const lists = usePeopleLists(session?.pubkey);
|
||||||
const profile = useProfile(session?.pubkey || ' ');
|
const profile = useProfile(session?.pubkey || ' ');
|
||||||
|
@ -38,8 +38,8 @@ const InfoPanel = ({ image, onClose, setViewMode, settings }: InfoPanelProps) =>
|
|||||||
{profile && (
|
{profile && (
|
||||||
<div className="info-panel-author">
|
<div className="info-panel-author">
|
||||||
{profile}
|
{profile}
|
||||||
{image?.noteId && (
|
{image.post.event.id && (
|
||||||
<a className="link" target="_blank" href={`https://nostrapp.link/#${nip19.noteEncode(image?.noteId)}`}>
|
<a className="link" target="_blank" href={`https://nostrapp.link/#${nip19.noteEncode(image.post.event.id)}`}>
|
||||||
<IconLink></IconLink>
|
<IconLink></IconLink>
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
|
@ -52,7 +52,7 @@ const MasonryImage = ({ image, onClick, index }: MasonryImageProps) => {
|
|||||||
{mediaIsVideo ? (
|
{mediaIsVideo ? (
|
||||||
<video
|
<video
|
||||||
className={`mason-image ${loaded ? 'show' : ''}`}
|
className={`mason-image ${loaded ? 'show' : ''}`}
|
||||||
data-node-id={image.noteId}
|
data-node-id={image.post.event.id}
|
||||||
key={image.url}
|
key={image.url}
|
||||||
controls={false}
|
controls={false}
|
||||||
autoPlay={false}
|
autoPlay={false}
|
||||||
@ -65,7 +65,7 @@ const MasonryImage = ({ image, onClick, index }: MasonryImageProps) => {
|
|||||||
<>
|
<>
|
||||||
<img
|
<img
|
||||||
referrerPolicy="no-referrer"
|
referrerPolicy="no-referrer"
|
||||||
data-node-id={image.noteId}
|
data-node-id={image.post.event.id}
|
||||||
onError={(e: SyntheticEvent<HTMLImageElement>) => {
|
onError={(e: SyntheticEvent<HTMLImageElement>) => {
|
||||||
console.log('not found: ', e.currentTarget.src);
|
console.log('not found: ', e.currentTarget.src);
|
||||||
e.currentTarget.src = '/notfound.png';
|
e.currentTarget.src = '/notfound.png';
|
||||||
|
@ -5,6 +5,7 @@ import './ScrollImage.css';
|
|||||||
import useOnScreen from '../../utils/useOnScreen';
|
import useOnScreen from '../../utils/useOnScreen';
|
||||||
import IconMicMuted from '../Icons/IconMicMuted';
|
import IconMicMuted from '../Icons/IconMicMuted';
|
||||||
import IconMicOn from '../Icons/IconMicOn';
|
import IconMicOn from '../Icons/IconMicOn';
|
||||||
|
import useWindowSize from '../../utils/useWindowSize';
|
||||||
|
|
||||||
interface ScrollImageProps {
|
interface ScrollImageProps {
|
||||||
image: NostrImage;
|
image: NostrImage;
|
||||||
@ -14,18 +15,42 @@ interface ScrollImageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ScrollImage = ({ image, currentImage, setCurrentImage, index }: ScrollImageProps) => {
|
const ScrollImage = ({ image, currentImage, setCurrentImage, index }: ScrollImageProps) => {
|
||||||
const isMobile = typeof screen.orientation !== 'undefined';
|
const { width } = useWindowSize();
|
||||||
|
const isMobile = useMemo(() => width && width <= 768, [width]);
|
||||||
|
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const videoRef = useRef<HTMLVideoElement>(null);
|
const videoRef = useRef<HTMLVideoElement>(null);
|
||||||
const [muted, setMuted] = useState(isMobile);
|
const [muted, setMuted] = useState(isMobile ? true : false);
|
||||||
const isVisible = useOnScreen(containerRef);
|
const isVisible = useOnScreen(containerRef);
|
||||||
const nearCurrentImage = useMemo(() => Math.abs((currentImage || 0) - index) < 3, [currentImage, index]);
|
const nearCurrentImage = useMemo(() => Math.abs((currentImage || 0) - index) < 3, [currentImage, index]);
|
||||||
const mediaIsVideo = useMemo(() => isVideo(image.url), [image.url]);
|
const mediaIsVideo = useMemo(() => isVideo(image.url), [image.url]);
|
||||||
|
|
||||||
const currentImageProxyUrl = useMemo(
|
const imageProxyUrl320 = useMemo(() => createImgProxyUrl(image.url, 320, -1), [image.url]);
|
||||||
() => (isMobile ? createImgProxyUrl(image.url, 800, -1) : image.url),
|
|
||||||
[image.url, isMobile]
|
const currentImageProxyUrl = useMemo(() => {
|
||||||
);
|
const imageProxyUrl800 = createImgProxyUrl(image.url, 800, -1);
|
||||||
|
const imageProxyUrl1920 = createImgProxyUrl(image.url, 1920, -1);
|
||||||
|
|
||||||
|
return width == undefined
|
||||||
|
? imageProxyUrl320
|
||||||
|
: width < 800
|
||||||
|
? imageProxyUrl320
|
||||||
|
: width < 1920
|
||||||
|
? imageProxyUrl800
|
||||||
|
: imageProxyUrl1920;
|
||||||
|
}, [image.url, imageProxyUrl320, width]);
|
||||||
|
|
||||||
|
const blurBgUrl = useMemo(() => {
|
||||||
|
if (mediaIsVideo) return '';
|
||||||
|
|
||||||
|
if (isMobile) {
|
||||||
|
// On mobile use the 200x200 grid image
|
||||||
|
return createImgProxyUrl(image.url, 200, 200);
|
||||||
|
} else {
|
||||||
|
// on Desktop use the 320x masonry image
|
||||||
|
return imageProxyUrl320;
|
||||||
|
}
|
||||||
|
}, [image.url, imageProxyUrl320, isMobile, mediaIsVideo]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const toggleVideoPause = (video: HTMLVideoElement | null) => {
|
const toggleVideoPause = (video: HTMLVideoElement | null) => {
|
||||||
@ -69,7 +94,7 @@ const ScrollImage = ({ image, currentImage, setCurrentImage, index }: ScrollImag
|
|||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
id={'sc' + index}
|
id={'sc' + index}
|
||||||
className="scroll-content"
|
className="scroll-content"
|
||||||
style={nearCurrentImage ? { backgroundImage: `url(${!mediaIsVideo ? currentImageProxyUrl : ''})` } : undefined}
|
style={nearCurrentImage ? { backgroundImage: `url(${blurBgUrl})` } : undefined}
|
||||||
>
|
>
|
||||||
{nearCurrentImage &&
|
{nearCurrentImage &&
|
||||||
(mediaIsVideo ? (
|
(mediaIsVideo ? (
|
||||||
|
@ -179,7 +179,7 @@ const SlideView = ({ settings, images, setViewMode }: SlideViewProps) => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{activeImages.map(image => (
|
{activeImages.map(image => (
|
||||||
<Slide key={image.url} noteId={image.noteId} url={image.url} paused={paused} type={image.type} />
|
<Slide key={image.url} noteId={image.post.event.id} url={image.url} paused={paused} type={image.type} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -9,8 +9,55 @@ export const publicUrl = import.meta.env.VITE_PUBLIC_URL || 'https://slidestr.ne
|
|||||||
type Topic = {
|
type Topic = {
|
||||||
name?: string;
|
name?: string;
|
||||||
tags: string[];
|
tags: string[];
|
||||||
|
nsfw?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* All posts with the following hashtags are flagged as adult / NSFW are not shown
|
||||||
|
by default. Users can enable this content through the adult content flag
|
||||||
|
in the UI or through a URL parameter.
|
||||||
|
*/
|
||||||
|
export const adultContentTags = [
|
||||||
|
'adult',
|
||||||
|
'ass',
|
||||||
|
'blowjob',
|
||||||
|
'boobs',
|
||||||
|
'boobstr',
|
||||||
|
'buttstr',
|
||||||
|
'erostr',
|
||||||
|
'erotic',
|
||||||
|
'freethenipple',
|
||||||
|
'friskyfriday',
|
||||||
|
'humpday',
|
||||||
|
'kink',
|
||||||
|
'kinkstr',
|
||||||
|
'lolita',
|
||||||
|
'milf',
|
||||||
|
'naked',
|
||||||
|
'nakedart',
|
||||||
|
'nasstr',
|
||||||
|
'nodestr',
|
||||||
|
'naughty',
|
||||||
|
'nsfw',
|
||||||
|
'nude',
|
||||||
|
'nudeart',
|
||||||
|
'nudes',
|
||||||
|
'onlyfans',
|
||||||
|
'orgasm',
|
||||||
|
'porn',
|
||||||
|
'pornhub',
|
||||||
|
'pornstr',
|
||||||
|
'pussy',
|
||||||
|
'sex',
|
||||||
|
'sexy',
|
||||||
|
'suicidegirls',
|
||||||
|
'thighstr',
|
||||||
|
'teenstr',
|
||||||
|
'tits',
|
||||||
|
'titstr',
|
||||||
|
'xxx',
|
||||||
|
'nostrqueen',
|
||||||
|
];
|
||||||
|
|
||||||
export const topics: { [key: string]: Topic } = {
|
export const topics: { [key: string]: Topic } = {
|
||||||
art: {
|
art: {
|
||||||
name: 'Art',
|
name: 'Art',
|
||||||
@ -29,26 +76,59 @@ export const topics: { [key: string]: Topic } = {
|
|||||||
'zeichnen',
|
'zeichnen',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
aiart: {
|
||||||
|
name: 'AI Art',
|
||||||
|
tags: [
|
||||||
|
'aiart',
|
||||||
|
'aiartists',
|
||||||
|
'aiartwork',
|
||||||
|
'automatic1111',
|
||||||
|
'generativeart',
|
||||||
|
'imgnai',
|
||||||
|
'midjourney',
|
||||||
|
'midjourneyart',
|
||||||
|
'stablediffusion',
|
||||||
|
],
|
||||||
|
},
|
||||||
bitcoin: { name: '₿itcoin', tags: ['bitcoin', 'plebchain'] },
|
bitcoin: { name: '₿itcoin', tags: ['bitcoin', 'plebchain'] },
|
||||||
nostr: { name: 'Nostr', tags: ['coffeechain', 'nostr', 'zapathon', 'grownostr', 'freedom', 'purple'] },
|
nostr: { name: 'Nostr', tags: ['coffeechain', 'nostr', 'zapathon', 'grownostr', 'freedom', 'purple'] },
|
||||||
animals: { name: 'Animals', tags: ['catstr', 'dogstr', 'animal', 'animals', 'bird', 'birds', 'pets'] },
|
animals: { name: 'Animals', tags: ['catstr', 'dogstr', 'animal', 'animals', 'bird', 'birds', 'pets'] },
|
||||||
photography: {
|
photography: {
|
||||||
name: 'Photography',
|
name: 'Photography',
|
||||||
tags: [
|
tags: [
|
||||||
|
'fujifilm',
|
||||||
|
'landscapephotography',
|
||||||
|
'moodoftheday',
|
||||||
'naturephotography',
|
'naturephotography',
|
||||||
'photo',
|
'photo',
|
||||||
|
'photobook',
|
||||||
'photography',
|
'photography',
|
||||||
'photos',
|
'photos',
|
||||||
'photostr',
|
'photostr',
|
||||||
'picoftheday',
|
'picoftheday',
|
||||||
'picstr',
|
'picstr',
|
||||||
'streetphotography',
|
'streetphotography',
|
||||||
'fujifilm',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
lifestyle: {
|
lifestyle: {
|
||||||
name: 'Lifestyle',
|
name: 'Lifestyle',
|
||||||
tags: ['fashion', 'flowerstr', 'style', 'weedstr', 'travel', 'travelstr', 'happy', 'life', 'love', 'hiking'],
|
tags: ['fashion', 'flowerstr', 'style', 'weedstr', 'happy', 'life', 'love', 'tattoo', 'tattoowomen'],
|
||||||
|
},
|
||||||
|
travel: {
|
||||||
|
name: 'Travel',
|
||||||
|
tags: [
|
||||||
|
'beach',
|
||||||
|
'camping',
|
||||||
|
'hiking',
|
||||||
|
'nature',
|
||||||
|
'ocean',
|
||||||
|
'travel',
|
||||||
|
'travelgram',
|
||||||
|
'travelling',
|
||||||
|
'travelstr',
|
||||||
|
'vacation',
|
||||||
|
'vanlife',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
food: {
|
food: {
|
||||||
name: 'Food / Cooking / Baking',
|
name: 'Food / Cooking / Baking',
|
||||||
@ -90,6 +170,11 @@ export const topics: { [key: string]: Topic } = {
|
|||||||
name: 'Bitcoin Atlantis / Madeira',
|
name: 'Bitcoin Atlantis / Madeira',
|
||||||
tags: ['atlantis', 'bitcoinatlantis', 'madeira', 'btcatlantis', 'soveng', 'funchal', 'freemadeira', 'ba24'],
|
tags: ['atlantis', 'bitcoinatlantis', 'madeira', 'btcatlantis', 'soveng', 'funchal', 'freemadeira', 'ba24'],
|
||||||
},
|
},
|
||||||
|
nsfw: {
|
||||||
|
name: 'NSFW / Adult Content',
|
||||||
|
tags: adultContentTags,
|
||||||
|
nsfw: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultHashTags = [
|
export const defaultHashTags = [
|
||||||
@ -148,52 +233,6 @@ export const visibleHashTags = [
|
|||||||
'zapathon',
|
'zapathon',
|
||||||
];
|
];
|
||||||
|
|
||||||
/* All posts with the following hashtags are flagged as adult / NSFW are not shown
|
|
||||||
by default. Users can enable this content through the adult content flag
|
|
||||||
in the UI or through a URL parameter.
|
|
||||||
*/
|
|
||||||
export const adultContentTags = [
|
|
||||||
'adult',
|
|
||||||
'ass',
|
|
||||||
'blowjob',
|
|
||||||
'boobs',
|
|
||||||
'boobstr',
|
|
||||||
'buttstr',
|
|
||||||
'erostr',
|
|
||||||
'erotic',
|
|
||||||
'freethenipple',
|
|
||||||
'friskyfriday',
|
|
||||||
'humpday',
|
|
||||||
'kink',
|
|
||||||
'kinkstr',
|
|
||||||
'lolita',
|
|
||||||
'milf',
|
|
||||||
'naked',
|
|
||||||
'nakedart',
|
|
||||||
'nasstr',
|
|
||||||
'nodestr',
|
|
||||||
'naughty',
|
|
||||||
'nsfw',
|
|
||||||
'nude',
|
|
||||||
'nudeart',
|
|
||||||
'nudes',
|
|
||||||
'onlyfans',
|
|
||||||
'orgasm',
|
|
||||||
'porn',
|
|
||||||
'pornhub',
|
|
||||||
'pornstr',
|
|
||||||
'pussy',
|
|
||||||
'sex',
|
|
||||||
'sexy',
|
|
||||||
'suicidegirls',
|
|
||||||
'thighstr',
|
|
||||||
'teenstr',
|
|
||||||
'tits',
|
|
||||||
'titstr',
|
|
||||||
'xxx',
|
|
||||||
'nostrqueen',
|
|
||||||
];
|
|
||||||
|
|
||||||
/* These are shown when using tags but hidden from global (unless NSFW content is enabled) */
|
/* These are shown when using tags but hidden from global (unless NSFW content is enabled) */
|
||||||
export const mixedAdultNPubs = [
|
export const mixedAdultNPubs = [
|
||||||
'npub12jedfuhk2wfr7syr38t2f55652khuyz9f88r63ftm0j2vudxq9sqq7677r', // Erikha
|
'npub12jedfuhk2wfr7syr38t2f55652khuyz9f88r63ftm0j2vudxq9sqq7677r', // Erikha
|
||||||
@ -211,6 +250,7 @@ export const adultNPubs = [
|
|||||||
'npub13n6ednsew67xk7hgse670z7849q5h8su5rgydxtl4lq3r5cx4ecqsd9af4', // Everybody, Every Body
|
'npub13n6ednsew67xk7hgse670z7849q5h8su5rgydxtl4lq3r5cx4ecqsd9af4', // Everybody, Every Body
|
||||||
'npub14agvvpaqjc922sn7vrkg769xujxh2wp2xdcd7xgrzec4ykyam6yshjepay',
|
'npub14agvvpaqjc922sn7vrkg769xujxh2wp2xdcd7xgrzec4ykyam6yshjepay',
|
||||||
'npub15asxgmzhextsxd8545rldcqgauq3ycxjta6a9m4x70p927jvltpq983udd', // Big Wanker
|
'npub15asxgmzhextsxd8545rldcqgauq3ycxjta6a9m4x70p927jvltpq983udd', // Big Wanker
|
||||||
|
'npub15xnjasjznk2tqude45pd7epjztgl9a550kn3pvztuarv9agfecrq7sv2ww', // Steel Seraphim
|
||||||
'npub16932qv3sz53t9fdlm2n7scct5ahe9fy9vsct36qd0wcwxm94gyks47dcg6', // Preggers
|
'npub16932qv3sz53t9fdlm2n7scct5ahe9fy9vsct36qd0wcwxm94gyks47dcg6', // Preggers
|
||||||
'npub16ye5pezunzcx8y0ecjquks0sr5jkj6lrhfjyu2n9qxt5cxgzrvcqgnvx8s', // Aru Moon
|
'npub16ye5pezunzcx8y0ecjquks0sr5jkj6lrhfjyu2n9qxt5cxgzrvcqgnvx8s', // Aru Moon
|
||||||
'npub17693mv2qu7mv67zqpcup9n502gmkuhytkxq3sw7qp50vlptq8f7syzv93d', // sha0wgoone
|
'npub17693mv2qu7mv67zqpcup9n502gmkuhytkxq3sw7qp50vlptq8f7syzv93d', // sha0wgoone
|
||||||
@ -221,6 +261,7 @@ export const adultNPubs = [
|
|||||||
'npub1935j9y7lzyu8mx0zm8mcr4njzrsautl66ms0w3z7wyea04zh85psqdc3v6',
|
'npub1935j9y7lzyu8mx0zm8mcr4njzrsautl66ms0w3z7wyea04zh85psqdc3v6',
|
||||||
'npub19e2tewftsy7ysd6hhkc4wn2czd4ku34z7wqkw5y4q8lm8fzhgxjsfhw825', // Waifposter88
|
'npub19e2tewftsy7ysd6hhkc4wn2czd4ku34z7wqkw5y4q8lm8fzhgxjsfhw825', // Waifposter88
|
||||||
'npub19sjqp4cvlv2quj0rls8lfs9sy2yquclq60xhatjrjhdu55qh7jtq9v8wy4', // 中本聰
|
'npub19sjqp4cvlv2quj0rls8lfs9sy2yquclq60xhatjrjhdu55qh7jtq9v8wy4', // 中本聰
|
||||||
|
'npub19v2wlfdsrvcdhjlvk2ur2wgyc30ult76flhyzaatew5n432a6ahs6ptsgt', // 纪唯一
|
||||||
'npub19xwjw7f23nsmnsd0j72mvhrdswt4cp6urc5el2zuu8se3yfu87ess524je', // Gone Wild (NSFW)
|
'npub19xwjw7f23nsmnsd0j72mvhrdswt4cp6urc5el2zuu8se3yfu87ess524je', // Gone Wild (NSFW)
|
||||||
'npub1acwrv7aqgu949mw0zxmw2akgsjqp574nnq4vcl9wln5355q79w5ssv9qxg', // Arianna
|
'npub1acwrv7aqgu949mw0zxmw2akgsjqp574nnq4vcl9wln5355q79w5ssv9qxg', // Arianna
|
||||||
'npub1acwrv7aqgu949mw0zxmw2akgsjqp574nnq4vcl9wln5355q79w5ssv9qxg', // Arianna
|
'npub1acwrv7aqgu949mw0zxmw2akgsjqp574nnq4vcl9wln5355q79w5ssv9qxg', // Arianna
|
||||||
@ -228,11 +269,15 @@ export const adultNPubs = [
|
|||||||
'npub1apr6dy5z4f0qs4cnswxj0gf37g46jxvh7xgwgs4wvzm6stu8f0asd4996r', // Anime Girl
|
'npub1apr6dy5z4f0qs4cnswxj0gf37g46jxvh7xgwgs4wvzm6stu8f0asd4996r', // Anime Girl
|
||||||
'npub1ccs7rlmctzzv6sj5qcjd3fdlys8zr3q6mnj30l4r4n6xp999yx7qg5qwtg', // gynoiddolls
|
'npub1ccs7rlmctzzv6sj5qcjd3fdlys8zr3q6mnj30l4r4n6xp999yx7qg5qwtg', // gynoiddolls
|
||||||
'npub1csk2wg33ee9kutyps4nmevyv3putfegj7yd0emsp44ph32wvmamqs7uyan', // Lilura
|
'npub1csk2wg33ee9kutyps4nmevyv3putfegj7yd0emsp44ph32wvmamqs7uyan', // Lilura
|
||||||
|
'npub1curnt7jtq8mhl9fcswnwvuvc9ccm6lvsdv4kzydx75v92kldrvdqh7sq09', // NOT NSFW but spammy ai pictures
|
||||||
|
'npub1d5ygkef6r0l7w29ek9l9c7hulsvdshms2qh74jp5qpfyad4g6h5s4ap6lz', // 莫谈国事
|
||||||
'npub1dn42tzy8v8m2xu4y38djf28dfugf5vkg2uucueeldvmucdlcwgjsk49856', // Mila
|
'npub1dn42tzy8v8m2xu4y38djf28dfugf5vkg2uucueeldvmucdlcwgjsk49856', // Mila
|
||||||
'npub1e4n8nah09he25slv00dz3kav3jsu5jvp83aya234ejumcmu2xseqwrp6pl', // Svenno(NSFW)
|
'npub1e4n8nah09he25slv00dz3kav3jsu5jvp83aya234ejumcmu2xseqwrp6pl', // Svenno(NSFW)
|
||||||
|
'npub1f3n7hq0a6vyfsjrv9vfdwtasa0g98ve96he68rxsvq9x6cl8tvxqmv6ca4', // Lady Sex (nude anime)
|
||||||
'npub1femd0mrawr0jmtjr2jwa2nm90haxrpglzdt6tt0djrsav39e53asf74aer', // FemDom Raw
|
'npub1femd0mrawr0jmtjr2jwa2nm90haxrpglzdt6tt0djrsav39e53asf74aer', // FemDom Raw
|
||||||
'npub1fevdattp2nd69c47cvldjp73hd3rjqynt9j7azgsjrdlt6jmhx9qagw3la', // Nova
|
'npub1fevdattp2nd69c47cvldjp73hd3rjqynt9j7azgsjrdlt6jmhx9qagw3la', // Nova
|
||||||
'npub1fh8e9pnm8rfln0k7c6uh8wrvmva8enkdzsgzsc7v9jk97up23ewqs6kuue', // nostrporn
|
'npub1fh8e9pnm8rfln0k7c6uh8wrvmva8enkdzsgzsc7v9jk97up23ewqs6kuue', // nostrporn
|
||||||
|
'npub1fr8lj8ny89jm93lk977494le5u2qmhuxg55n7lmtm0e50khzdxxq5almwg', // terry
|
||||||
'npub1fut75jn7hztc248vz3g8vfsdtwuy95l6khw533k6dsstsdrxkussf9ax6g', // bliss (not many nude art posts)
|
'npub1fut75jn7hztc248vz3g8vfsdtwuy95l6khw533k6dsstsdrxkussf9ax6g', // bliss (not many nude art posts)
|
||||||
'npub1ga79p6qsjh0xd343q3du2unf2gl6gk0rde36c06mafxkrssmnnesxyzcss', // Orange Incest 🔞
|
'npub1ga79p6qsjh0xd343q3du2unf2gl6gk0rde36c06mafxkrssmnnesxyzcss', // Orange Incest 🔞
|
||||||
'npub1grssdyrmdgy5gw5umg50u6rrl9nk738lw4qg2thpcqqaf3lypkqsxt7lhg', // Shades of Red
|
'npub1grssdyrmdgy5gw5umg50u6rrl9nk738lw4qg2thpcqqaf3lypkqsxt7lhg', // Shades of Red
|
||||||
@ -264,30 +309,27 @@ export const adultNPubs = [
|
|||||||
'npub1qg550au9hqmpgye4kfrtj7yt85dn60ty5hk0hcm7pktq6g6mzugsufnfcx', // Poppy Clements
|
'npub1qg550au9hqmpgye4kfrtj7yt85dn60ty5hk0hcm7pktq6g6mzugsufnfcx', // Poppy Clements
|
||||||
'npub1qnpzqvzjxy79wpuvylw65gkh8n7pk62up9nc63a45a23mv0sf6us62qk5n', // 🔞▶️Play & ⏸️Pause 🔞
|
'npub1qnpzqvzjxy79wpuvylw65gkh8n7pk62up9nc63a45a23mv0sf6us62qk5n', // 🔞▶️Play & ⏸️Pause 🔞
|
||||||
'npub1qrgawjx8cvc0qsd5te5dep3ynmklsye55gu0w9d4y6tk0vcxduassqqgzf', // dustycity
|
'npub1qrgawjx8cvc0qsd5te5dep3ynmklsye55gu0w9d4y6tk0vcxduassqqgzf', // dustycity
|
||||||
|
'npub1rqnhn57h5fpc5ugd0mwpkkjsfpgz0uf0s4340w9gp5aykze8kvdsr6kq38', // 潔💋
|
||||||
'npub1rv08kght99a7xwckm0qpmzw09m5gwppequgqd8lwu74eakgaavwsp5cjtw', // CuratedNSFW
|
'npub1rv08kght99a7xwckm0qpmzw09m5gwppequgqd8lwu74eakgaavwsp5cjtw', // CuratedNSFW
|
||||||
'npub1sg7rwnf96a0fhl85xlvq0unumqqh89qaygwcdy5d3ue8209ekt2suhxg7u', // Anime Mommies Bot
|
'npub1sg7rwnf96a0fhl85xlvq0unumqqh89qaygwcdy5d3ue8209ekt2suhxg7u', // Anime Mommies Bot
|
||||||
'npub1sgmuwdfzq2asrh68p6ul9chp32y4938qa7ns637qgmeqgglhtwmq4l5xl9', // Nudeful Art / Athos
|
'npub1sgmuwdfzq2asrh68p6ul9chp32y4938qa7ns637qgmeqgglhtwmq4l5xl9', // Nudeful Art / Athos
|
||||||
'npub1skvfwq29xn92k08mu2584kx5x6ymz62askpnzjp9d3s8us68pemsmt78a4', // pornstarxyz
|
'npub1skvfwq29xn92k08mu2584kx5x6ymz62askpnzjp9d3s8us68pemsmt78a4', // pornstarxyz
|
||||||
'npub1suddec4n2jv50pgn9eea35r4k83ahr4mcj0zv2uec36w6jeuwagq82xjgl', // quiet.enjoyer
|
'npub1suddec4n2jv50pgn9eea35r4k83ahr4mcj0zv2uec36w6jeuwagq82xjgl', // quiet.enjoyer
|
||||||
|
'npub1t07mr7m65lg3ecr5eapu6qe4ayt2wgjpqjs8x58m5kx2r2cutsyqyzzzs9', // NOT NSFW but spammy ai pictures
|
||||||
'npub1t252vm7u5qmfwv3k70g6rl2ue7ctvtvrnd60vy8jh5suglv8pw2snyyzfq', // 20th Century Foxes (NSFW)
|
'npub1t252vm7u5qmfwv3k70g6rl2ue7ctvtvrnd60vy8jh5suglv8pw2snyyzfq', // 20th Century Foxes (NSFW)
|
||||||
'npub1thsprukxnc8rxqggnesqp2wg2temhaadzhhg7n4pttpveyqedlwsqgge9q', // Harmony. Corrupted.
|
'npub1thsprukxnc8rxqggnesqp2wg2temhaadzhhg7n4pttpveyqedlwsqgge9q', // Harmony. Corrupted.
|
||||||
'npub1tsrs6ptjnq5hluxawfme5sfxalfscapequm3ej0yfw65scwu8lys8q7y7l', // 💜 🔞EUPHORIA 🔞💜
|
'npub1tsrs6ptjnq5hluxawfme5sfxalfscapequm3ej0yfw65scwu8lys8q7y7l', // 💜 🔞EUPHORIA 🔞💜
|
||||||
'npub1ulafm4d3n7ukl7yzg4hfnhfjut74nym5p83e3d67l3j62yc6ysqqrancw2', // naked
|
'npub1ulafm4d3n7ukl7yzg4hfnhfjut74nym5p83e3d67l3j62yc6ysqqrancw2', // naked
|
||||||
'npub1v3rnmlms82wgxejxwn7rr6kjruy3ty0l4084dx2zp3tn8dlxv28sjnp6pf', // High Elf Archer
|
'npub1v3rnmlms82wgxejxwn7rr6kjruy3ty0l4084dx2zp3tn8dlxv28sjnp6pf', // High Elf Archer
|
||||||
'npub1ve4ztpqvlgu3v6hgrvc4lrdl2ernue7lq2h8tcgaksrkxlm7gnsqkjmz4e', // bluntkaraoke
|
'npub1ve4ztpqvlgu3v6hgrvc4lrdl2ernue7lq2h8tcgaksrkxlm7gnsqkjmz4e', // bluntkaraoke
|
||||||
|
'npub1vmd8l5h60wqzp5yyjdutleyntqlq86yqxhwxwayek488rngtaras2z99sh', // ANDREIITA
|
||||||
|
'npub1vyxmz6xgf84f8x73ww7vts6apag3ngs957eterw5lgay2z7f55tskahsja', // Homer
|
||||||
'npub1wmsn8fch7kwt987jcdx06uuapn6pwzau59pvy0ql5d3xlmnxa2csj3c5p4', // StefsPicks
|
'npub1wmsn8fch7kwt987jcdx06uuapn6pwzau59pvy0ql5d3xlmnxa2csj3c5p4', // StefsPicks
|
||||||
'npub1y77j6jm5hw34xl5m85aumltv88arh2s7q383allkpfe4muarzc5qzfgru0', // sexy-models
|
'npub1y77j6jm5hw34xl5m85aumltv88arh2s7q383allkpfe4muarzc5qzfgru0', // sexy-models
|
||||||
'npub1yk6fz5gx6m79g3xvxk3ca9u87mh8t73w2u2tzvdmrqwauvsqtsnsq6rcqm', // bloodywing
|
'npub1yk6fz5gx6m79g3xvxk3ca9u87mh8t73w2u2tzvdmrqwauvsqtsnsq6rcqm', // bloodywing
|
||||||
|
'npub1ylq5s3xsdmzgzvgzll6ghcs3qa8a9ajl955hj4tcpmyruvjsl8nq5wqhd8', // Dnera
|
||||||
'npub1ylrnf0xfp9wsmqthxlqjqyqj9yy27pnchjwjq93v3mq66ts7ftjs6x7dcq', // Welcome To The Jungle
|
'npub1ylrnf0xfp9wsmqthxlqjqyqj9yy27pnchjwjq93v3mq66ts7ftjs6x7dcq', // Welcome To The Jungle
|
||||||
'npub1z0xv9t5w6evrcg860kmgqq5tfj55mz84ta40uszjnfp9uhw2clkq63yrak', // ???
|
'npub1z0xv9t5w6evrcg860kmgqq5tfj55mz84ta40uszjnfp9uhw2clkq63yrak', // ???
|
||||||
'npub1f3n7hq0a6vyfsjrv9vfdwtasa0g98ve96he68rxsvq9x6cl8tvxqmv6ca4', // Lady Sex (nude anime)
|
|
||||||
'npub1ylq5s3xsdmzgzvgzll6ghcs3qa8a9ajl955hj4tcpmyruvjsl8nq5wqhd8', // Dnera
|
|
||||||
'npub1vmd8l5h60wqzp5yyjdutleyntqlq86yqxhwxwayek488rngtaras2z99sh', // ANDREIITA
|
|
||||||
'npub1d5ygkef6r0l7w29ek9l9c7hulsvdshms2qh74jp5qpfyad4g6h5s4ap6lz', // 莫谈国事
|
|
||||||
'npub1fr8lj8ny89jm93lk977494le5u2qmhuxg55n7lmtm0e50khzdxxq5almwg', // terry
|
|
||||||
|
|
||||||
'npub1t07mr7m65lg3ecr5eapu6qe4ayt2wgjpqjs8x58m5kx2r2cutsyqyzzzs9', // NOT NSFW but spammy ai pictures
|
|
||||||
'npub1curnt7jtq8mhl9fcswnwvuvc9ccm6lvsdv4kzydx75v92kldrvdqh7sq09', // NOT NSFW but spammy ai pictures
|
|
||||||
];
|
];
|
||||||
|
|
||||||
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());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NDKEvent, NDKFilter, NDKTag } from '@nostr-dev-kit/ndk';
|
import { NDKEvent, NDKFilter, NDKTag } from '@nostr-dev-kit/ndk';
|
||||||
import { adultContentTags, adultPublicKeys, mixedAdultNPubs } from './env';
|
import { adultContentTags, adultPublicKeys, imageProxy, mixedAdultNPubs } from './env';
|
||||||
import uniq from 'lodash/uniq';
|
import uniq from 'lodash/uniq';
|
||||||
import { unixNow } from '../ngine/time';
|
import { unixNow } from '../ngine/time';
|
||||||
|
|
||||||
@ -130,5 +130,5 @@ export const createImgProxyUrl = (url: string, width = 200, height = 200) => {
|
|||||||
|
|
||||||
const heightParam = height < 0 ? '' : ':' + height;
|
const heightParam = height < 0 ? '' : ':' + height;
|
||||||
|
|
||||||
return `https://imgproxy.slidestr.net/insecure/f:webp/rs:fill:${width}${heightParam}/plain/${url}`;
|
return `${imageProxy}/insecure/f:webp/rs:fill:${width}${heightParam}/plain/${url}`;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user