From d6ee3d4270073aa6d2f45d310bad5a06e7ed0d42 Mon Sep 17 00:00:00 2001 From: Florian Maul Date: Thu, 20 Jul 2023 23:01:06 +0200 Subject: [PATCH] chore: some refactoring --- src/components/SlideShow.css | 27 ++++++- src/components/SlideShow.tsx | 112 +++++++-------------------- src/components/env.ts | 11 +++ src/components/nostrImageDownload.ts | 68 ++++++++++++++++ 4 files changed, 132 insertions(+), 86 deletions(-) create mode 100644 src/components/env.ts create mode 100644 src/components/nostrImageDownload.ts diff --git a/src/components/SlideShow.css b/src/components/SlideShow.css index 78dca3e..eefaf63 100644 --- a/src/components/SlideShow.css +++ b/src/components/SlideShow.css @@ -1,4 +1,3 @@ - @keyframes showImage { from { scale: 1.2; @@ -50,11 +49,11 @@ @keyframes spin { from { - transform: translate(-50%, -50%) rotate(0deg); + transform: rotate(0deg); } to { - transform: translate(-50%, -50%) rotate(360deg); + transform: rotate(360deg); } } @@ -153,6 +152,28 @@ opacity: 1; } +.bottomPanel .caption { + color: white; + font-size: 2em; + font-weight: 500; + margin-bottom: 0.5em; + max-width: 80%; + text-align: center; + margin: auto; +} + +@media screen and (max-width: 960px) { + .bottomPanel .caption { + font-size: 1.5em; + } +} + +@media screen and (max-width: 600px) { + .bottomPanel .caption { + font-size: 1em; + } +} + .centerSymbol { position: absolute; top: 50%; diff --git a/src/components/SlideShow.tsx b/src/components/SlideShow.tsx index 972ba13..f250098 100644 --- a/src/components/SlideShow.tsx +++ b/src/components/SlideShow.tsx @@ -1,13 +1,21 @@ import { useNDK } from "@nostr-dev-kit/ndk-react"; import "./SlideShow.css"; -import { nip19 } from "nostr-tools"; import React, { useEffect, useRef, useState } from "react"; -import { NDKFilter, NDKUser } from "@nostr-dev-kit/ndk"; import AuthorProfile from "./AuthorProfile"; import IconFullScreen from "./IconFullScreen"; import Slide from "./Slide"; import { Helmet } from "react-helmet"; import useDebouncedEffect from "../utils/useDebouncedEffect"; +import { + NostrImage, + buildFilter, + extractImageUrls, + hasContentWarning, + isReply, + prepareContent, + urlFix, +} from "./nostrImageDownload"; +import { appName } from "./env"; /* FEATURES: @@ -33,80 +41,6 @@ FEATURES: - Support Deleted Events */ -type NostrImage = { - url: string; - author: NDKUser; - content?: string; -}; - -const buildFilter = ( - setTitle: React.Dispatch>, - until?: number, - tags?: string, - npub?: string -) => { - const filter: NDKFilter = { - kinds: [1], - limit: 30, // some relays have a low limit - until, - }; - - if (npub) { - filter.authors = [nip19.decode(npub).data as string]; - } else { - if (tags) { - filter["#t"] = tags.split(","); - setTitle("#" + tags.replace(",", " #") + " | slidestr.net"); - } else { - setTitle("Random photos from popular hashtags | slidestr.net"); - - // Default tags - filter["#t"] = [ - "photography", - "photostr", - "artstr", - "art", - "catstr", - "dogstr", - "nature", - ]; - } - } - - return filter; -}; - -const prepareContent = (content: string) => { - return content - .replace(/https?:\/\/[^\s]+/g, "") // remove all urls - .replace(/#[^\s]+/g, ""); // remove all tags -}; - -const urlFix = (url: string) => { - // use cdn for nostr.build - return url.replace(/https?:\/\/nostr.build/, "https://cdn.nostr.build"); -}; - -function extractImageUrls(text: string): string[] { - const urlRegex = /(https?:\/\/[^\s]+)/g; - return (text.match(urlRegex) || []).map((u) => urlFix(u)); -} - -const isReply = (event: any) => { - // ["e", "aab5a68f29d76a04ad79fe7e489087b802ee0f946689d73b0e15931dd40a7af3", "", "reply"] - return ( - event.tags.filter((t: string[]) => t[0] === "e" && t[3] === "reply") - .length > 0 - ); -}; - -const hasContentWarning = (event: any) => { - // ["content-warning", "NSFW: implied nudity"] - return ( - event.tags.filter((t: string[]) => t[0] === "content-warning").length > 0 - ); -}; - let oldest = Infinity; let maxFetchCount = 20; let eventsReceived = 0; @@ -122,7 +56,7 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => { const images = useRef([]); const [activeImages, setActiveImages] = useState([]); const upcommingImage = useRef(); - const [title, setTitle] = useState("slidestr.net"); + const [title, setTitle] = useState(appName); const [paused, setPaused] = useState(false); const [loading, setLoading] = useState(true); const [activeNpub, setActiveNpub] = useState(undefined); @@ -224,7 +158,7 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => { // Make sure we have an image to start with but only trigger once if (upcommingImage.current === undefined && images.current.length > 2) { - queueNextImage(1000); + queueNextImage(1000); } }, [posts]); @@ -279,7 +213,7 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => { (activeProfile.displayName || activeProfile.name) ) { setTitle( - activeProfile.displayName || activeProfile.name + " | slidestr.net" + activeProfile.displayName || activeProfile.name + ` | ${appName}` ); } }, [activeProfile]); @@ -313,11 +247,23 @@ const SlideShow = ({ tags, npub }: SlideShowProps) => { )} - {loading &&
- -
} + {loading && ( +
+ + + +
+ )} - {activeContent &&
{activeContent}
} + {activeContent && ( +
+
{activeContent}
+
+ )} {activeProfile && ( >, + until?: number, + tags?: string, + npub?: string +) => { + const filter: NDKFilter = { + kinds: [1], + limit: 30, // some relays have a low limit + until, + }; + + if (npub) { + + filter.authors = [nip19.decode(npub).data as string]; + } else { + if (tags) { + setTitle("#" + tags.replace(",", " #") + ` | ${appName}`); + filter["#t"] = tags.split(","); + } else { + setTitle(`Random photos from popular hashtags | ${appName}`); + filter["#t"] = defaultHashTags; + } + } + + return filter; +}; + +export const prepareContent = (content: string) => { + return content + .replace(/https?:\/\/[^\s]+/g, "") // remove all urls + .replace(/#[^\s]+/g, ""); // remove all tags +}; + +export const urlFix = (url: string) => { + // use cdn for nostr.build + return url.replace(/https?:\/\/nostr.build/, "https://cdn.nostr.build"); +}; + +export const extractImageUrls = (text: string): string[] => { + const urlRegex = /(https?:\/\/[^\s]+)/g; + return (text.match(urlRegex) || []).map((u) => urlFix(u)); +}; + +export const isReply = (event: any) => { + // ["e", "aab5a68f29d76a04ad79fe7e489087b802ee0f946689d73b0e15931dd40a7af3", "", "reply"] + return ( + event.tags.filter((t: string[]) => t[0] === "e" && t[3] === "reply") + .length > 0 + ); +}; + +export const hasContentWarning = (event: any) => { + // ["content-warning", "NSFW: implied nudity"] + return ( + event.tags.filter((t: string[]) => t[0] === "content-warning").length > 0 + ); +};