feat: nsfw toggle

This commit is contained in:
Damien Ostler 2024-05-27 20:40:23 -04:00
parent 43432a8bcd
commit af0dd625b4
3 changed files with 35 additions and 17 deletions

View File

@ -20,7 +20,9 @@ export async function GET(
const galleryId = params.id.toLowerCase().replace(/\s+/g, '_'); const galleryId = params.id.toLowerCase().replace(/\s+/g, '_');
const supabase = createClient(); const supabase = createClient();
const user = await supabase.auth.getUser(); const user = await supabase.auth.getUser();
const url = new URL(request.url);
const search = url.searchParams.get("nsfw");
const nsfw = search === "true";
const { data: gallery, error: galleryError } = await supabase const { data: gallery, error: galleryError } = await supabase
.from('galleries') .from('galleries')
@ -49,7 +51,7 @@ export async function GET(
.select('*') .select('*')
.eq('user_id', userId) .eq('user_id', userId)
.single(); .single();
if(gallery.nsfw){ if(nsfw && gallery.nsfw){
blobBuffer = await blurImage(blobBuffer); blobBuffer = await blurImage(blobBuffer);
} }
const contentType = files[0].name.endsWith('.png') ? 'image/png' : 'image/jpeg'; const contentType = files[0].name.endsWith('.png') ? 'image/png' : 'image/jpeg';

View File

@ -12,6 +12,7 @@ function PageComponent() {
const supabase = createClient(); const supabase = createClient();
const [showNSFW, setShowNSFW] = useState<boolean>(true);
const [randomIds, setRandomIds] = useState<string[]>([]); // replace any with your gallery type const [randomIds, setRandomIds] = useState<string[]>([]); // replace any with your gallery type
const [isOpen, setIsOpen] = useState<boolean>(false); const [isOpen, setIsOpen] = useState<boolean>(false);
const [galleries, setGalleries] = useState<any[]>([]); // replace any with your gallery type const [galleries, setGalleries] = useState<any[]>([]); // replace any with your gallery type
@ -47,7 +48,7 @@ function PageComponent() {
const getData = async () => { const getData = async () => {
let { data: { user } } = await supabase.auth.getUser(); let { data: { user } } = await supabase.auth.getUser();
const galleriesResponse = await fetch(`/api/galleries?search=`+search, { const galleriesResponse = await fetch(`/api/galleries?search=`+search+'&nsfw='+showNSFW, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@ -66,7 +67,7 @@ function PageComponent() {
useEffect(() => { useEffect(() => {
getData(); getData();
}, [selectedTags,search]); }, [selectedTags,search,showNSFW]);
const handleTagClick = (tag: number) => { const handleTagClick = (tag: number) => {
if (selectedTags.includes(tag)) { if (selectedTags.includes(tag)) {
@ -89,16 +90,28 @@ function PageComponent() {
<section className="flex items-center w-full p-8 pt-20 opacity-90 animate-jump-in animate-once animate-duration-500"> <section className="flex items-center w-full p-8 pt-20 opacity-90 animate-jump-in animate-once animate-duration-500">
{(tags.length>0) ? ( {(tags.length>0) ? (
<div className="container mx-auto py-8"> <div className="container mx-auto py-8">
<div className="relative w-full mx-auto">
<input <input
className=" w-full md:w-1/2 text-neroshi-blue-950 h-16 px-3 rounded mb-8 focus:outline-none focus:shadow-outline text-xl px-8 shadow-lg mx-auto" className="w-full text-neroshi-blue-950 h-16 px-3 rounded mb-8 focus:outline-none focus:shadow-outline text-xl px-8 shadow-lg"
type="search" type="search"
placeholder="Search by title..." placeholder="Search by title..."
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
style={{ style={{
animation: 'expandFromLeft 2s ease-out forwards' animation: 'expandFromLeft 2s ease-out forwards',
}} paddingRight: '2rem', // make room for the checkbox
/> }}
/>
<label htmlFor="toggleNSFW" className="absolute right-0 top-0 h-full mr-2 flex items-center text-neroshi-blue-950 animate-fade animate-once animate-duration-500 animate-delay-[2000ms] animate-ease-out">
Censor NSFW
<input
id="toggleNSFW"
type="checkbox"
checked={showNSFW}
onChange={()=>setShowNSFW(!showNSFW)}
className="form-checkbox h-5 w-5 text-neroshi-blue-950 ml-2 "
/>
</label>
</div>
{(tags.length>0) ? ( {(tags.length>0) ? (
<nav className="grid grid-cols-4 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10 gap-4 justify-items-center"> <nav className="grid grid-cols-4 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10 gap-4 justify-items-center">
{tags.map((tag, index) => ( {tags.map((tag, index) => (
@ -128,11 +141,12 @@ function PageComponent() {
{galleries && galleries.map((gallery, index) => ( {galleries && galleries.map((gallery, index) => (
<div className="mx-auto"> <div className="mx-auto">
<GalleryThumbnail <GalleryThumbnail
key={gallery.name} key={gallery.name+" "+showNSFW}
id={gallery.name} id={gallery.name}
title={gallery.name} title={gallery.name}
tags={gallery.tags} tags={gallery.tags}
columns={gallery.columns} columns={gallery.columns}
showNsfw={showNSFW}
subscription={gallery.tier as string} subscription={gallery.tier as string}
onSelect={selectGallery} onSelect={selectGallery}
nsfw={gallery.nsfw} nsfw={gallery.nsfw}

View File

@ -7,16 +7,18 @@ interface GalleryThumbnailProps {
title: string; title: string;
subscription: string; subscription: string;
tags: string[]; tags: string[];
showNsfw: boolean;
nsfw: boolean; nsfw: boolean;
} }
const GalleryThumbnail = ({ id, columns, onSelect, title,nsfw, subscription, tags }: GalleryThumbnailProps) => { const GalleryThumbnail = ({ id, columns, onSelect, title,showNsfw, nsfw, subscription, tags }: GalleryThumbnailProps) => {
const [galleryId, setGalleryId] = useState<string>(id); const [galleryId, setGalleryId] = useState<string>(id);
const [thumbnailUrl, setThumbnailUrl] = useState<string>(''); const [thumbnailUrl, setThumbnailUrl] = useState<string>('');
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState<boolean>(true);
const [galleryCollumns, setColumns] = useState<number>(columns); const [galleryCollumns, setColumns] = useState<number>(columns);
const [imageCount, setImageCount] = useState<number>(0); const [imageCount, setImageCount] = useState<number>(0);
const [nsfwState, setNsfw] = useState<boolean>(nsfw); const [nsfwState, setNsfw] = useState<boolean>(nsfw);
const [showNsfwState, setShowNsfw] = useState<boolean>(showNsfw);
const [subscriptionState, setSubscription] = useState<string>(subscription); const [subscriptionState, setSubscription] = useState<string>(subscription);
const [tagsState, setTags] = useState<string[]>(tags); const [tagsState, setTags] = useState<string[]>(tags);
const openGallery = () => { const openGallery = () => {
@ -25,7 +27,7 @@ const GalleryThumbnail = ({ id, columns, onSelect, title,nsfw, subscription, tag
const getData = async () => { const getData = async () => {
setIsLoading(true); setIsLoading(true);
const thumbnailResponse = await fetch('/api/galleries/' + title + '/thumbnail'); const thumbnailResponse = await fetch('/api/galleries/' + title + '/thumbnail?nsfw=' + showNsfwState);
const thumbnailUrl = await thumbnailResponse.text(); const thumbnailUrl = await thumbnailResponse.text();
const imagesCountResponse = await fetch('/api/galleries/' + title + '/images/count'); const imagesCountResponse = await fetch('/api/galleries/' + title + '/images/count');
const imageCount = await imagesCountResponse.json() as number; const imageCount = await imagesCountResponse.json() as number;