From 95aa6f78bba840db173a65ceaccf14cb06d0693d Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 28 Nov 2023 14:20:35 +0200 Subject: [PATCH] CONFIG.bypassImgProxyError to load directly from origin --- packages/app/config/default.json | 1 + packages/app/config/iris.json | 1 + packages/app/custom.d.ts | 1 + packages/app/src/Element/Feed/Generic.tsx | 3 +- packages/app/src/Element/Feed/Timeline.tsx | 2 +- .../app/src/Element/Feed/TimelineFollows.tsx | 2 +- .../app/src/Element/Feed/TimelineFragment.tsx | 65 ------------------ .../app/src/Element/Feed/TimelineRenderer.tsx | 68 +++++++++++++++++++ packages/app/src/Element/ProxyImg.tsx | 3 +- packages/app/src/Element/User/Avatar.css | 3 + packages/app/src/Element/User/Avatar.tsx | 30 ++++---- packages/app/src/Pages/DeckLayout.tsx | 2 +- 12 files changed, 93 insertions(+), 88 deletions(-) create mode 100644 packages/app/src/Element/Feed/TimelineRenderer.tsx diff --git a/packages/app/config/default.json b/packages/app/config/default.json index c457dd6d..efb4e0f6 100644 --- a/packages/app/config/default.json +++ b/packages/app/config/default.json @@ -12,6 +12,7 @@ "animalNamePlaceholders": false, "showNoteBroadcaster": true, "defaultZapPoolFee": 0.5, + "bypassImgProxyError": false, "features": { "analytics": true, "subscriptions": true, diff --git a/packages/app/config/iris.json b/packages/app/config/iris.json index 78e73278..c84bfa0b 100644 --- a/packages/app/config/iris.json +++ b/packages/app/config/iris.json @@ -12,6 +12,7 @@ "animalNamePlaceholders": true, "showNoteBroadcaster": false, "defaultZapPoolFee": 0.5, + "bypassImgProxyError": true, "features": { "analytics": true, "subscriptions": false, diff --git a/packages/app/custom.d.ts b/packages/app/custom.d.ts index b3a5df59..8e3665b4 100644 --- a/packages/app/custom.d.ts +++ b/packages/app/custom.d.ts @@ -53,6 +53,7 @@ declare const CONFIG: { animalNamePlaceholders: boolean; showNoteBroadcaster: boolean; defaultZapPoolFee: number; + bypassImgProxyError: boolean; features: { analytics: boolean; subscriptions: boolean; diff --git a/packages/app/src/Element/Feed/Generic.tsx b/packages/app/src/Element/Feed/Generic.tsx index f9b78428..48e59bec 100644 --- a/packages/app/src/Element/Feed/Generic.tsx +++ b/packages/app/src/Element/Feed/Generic.tsx @@ -1,7 +1,8 @@ import { NostrLink, NoteCollection, ReqFilter, RequestBuilder } from "@snort/system"; import { useReactions, useRequestBuilder } from "@snort/system-react"; import { useMemo } from "react"; -import { TimelineRenderer } from "./TimelineFragment"; + +import { TimelineRenderer } from "@/Element/Feed/TimelineRenderer"; export function GenericFeed({ link }: { link: NostrLink }) { const sub = useMemo(() => { diff --git a/packages/app/src/Element/Feed/Timeline.tsx b/packages/app/src/Element/Feed/Timeline.tsx index bdb20f17..91148e2a 100644 --- a/packages/app/src/Element/Feed/Timeline.tsx +++ b/packages/app/src/Element/Feed/Timeline.tsx @@ -7,8 +7,8 @@ import { dedupeByPubkey, findTag } from "@/SnortUtils"; import useTimelineFeed, { TimelineFeed, TimelineSubject } from "@/Feed/TimelineFeed"; import useModeration from "@/Hooks/useModeration"; import { LiveStreams } from "@/Element/LiveStreams"; -import { TimelineRenderer } from "./TimelineFragment"; import { unixNow } from "@snort/shared"; +import { TimelineRenderer } from "@/Element/Feed/TimelineRenderer"; export interface TimelineProps { postsOnly: boolean; diff --git a/packages/app/src/Element/Feed/TimelineFollows.tsx b/packages/app/src/Element/Feed/TimelineFollows.tsx index bfd2c143..0c327b5e 100644 --- a/packages/app/src/Element/Feed/TimelineFollows.tsx +++ b/packages/app/src/Element/Feed/TimelineFollows.tsx @@ -10,9 +10,9 @@ import useModeration from "@/Hooks/useModeration"; import { FollowsFeed } from "@/Cache"; import { LiveStreams } from "@/Element/LiveStreams"; import useLogin from "@/Hooks/useLogin"; -import { TimelineRenderer } from "./TimelineFragment"; import useHashtagsFeed from "@/Feed/HashtagsFeed"; import { ShowMoreInView } from "@/Element/Event/ShowMore"; +import { TimelineRenderer } from "@/Element/Feed/TimelineRenderer"; export interface TimelineFollowsProps { postsOnly: boolean; diff --git a/packages/app/src/Element/Feed/TimelineFragment.tsx b/packages/app/src/Element/Feed/TimelineFragment.tsx index d9dd08c9..93396c97 100644 --- a/packages/app/src/Element/Feed/TimelineFragment.tsx +++ b/packages/app/src/Element/Feed/TimelineFragment.tsx @@ -1,11 +1,7 @@ import { ReactNode, useCallback } from "react"; -import { FormattedMessage } from "react-intl"; -import { useInView } from "react-intersection-observer"; import { TaggedNostrEvent } from "@snort/system"; import Note from "@/Element/Event/Note"; -import ProfileImage from "@/Element/User/ProfileImage"; -import Icon from "@/Icons/Icon"; import { findTag } from "@/SnortUtils"; export interface TimelineFragment { @@ -14,67 +10,6 @@ export interface TimelineFragment { title?: ReactNode; } -export interface TimelineRendererProps { - frags: Array; - related: Array; - /** - * List of pubkeys who have posted recently - */ - latest: Array; - showLatest: (toTop: boolean) => void; - noteRenderer?: (ev: TaggedNostrEvent) => ReactNode; - noteOnClick?: (ev: TaggedNostrEvent) => void; - noteContext?: (ev: TaggedNostrEvent) => ReactNode; -} - -export function TimelineRenderer(props: TimelineRendererProps) { - const { ref, inView } = useInView(); - - return ( - <> - {props.latest.length > 0 && ( - <> -
props.showLatest(false)} ref={ref}> - {props.latest.slice(0, 3).map(p => { - return ; - })} - - -
- {!inView && ( -
props.showLatest(true)}> - {props.latest.slice(0, 3).map(p => { - return ; - })} - - -
- )} - - )} - {props.frags.map(f => ( - - ))} - - ); -} - export interface TimelineFragProps { frag: TimelineFragment; related: Array; diff --git a/packages/app/src/Element/Feed/TimelineRenderer.tsx b/packages/app/src/Element/Feed/TimelineRenderer.tsx new file mode 100644 index 00000000..f71f08a8 --- /dev/null +++ b/packages/app/src/Element/Feed/TimelineRenderer.tsx @@ -0,0 +1,68 @@ +import { useInView } from "react-intersection-observer"; +import ProfileImage from "@/Element/User/ProfileImage"; +import { FormattedMessage } from "react-intl"; +import Icon from "@/Icons/Icon"; +import { TaggedNostrEvent } from "@snort/system"; +import { ReactNode } from "react"; +import { TimelineFragment } from "@/Element/Feed/TimelineFragment"; + +export interface TimelineRendererProps { + frags: Array; + related: Array; + /** + * List of pubkeys who have posted recently + */ + latest: Array; + showLatest: (toTop: boolean) => void; + noteRenderer?: (ev: TaggedNostrEvent) => ReactNode; + noteOnClick?: (ev: TaggedNostrEvent) => void; + noteContext?: (ev: TaggedNostrEvent) => ReactNode; +} + +export function TimelineRenderer(props: TimelineRendererProps) { + const { ref, inView } = useInView(); + + return ( + <> + {props.latest.length > 0 && ( + <> +
props.showLatest(false)} ref={ref}> + {props.latest.slice(0, 3).map(p => { + return ; + })} + + +
+ {!inView && ( +
props.showLatest(true)}> + {props.latest.slice(0, 3).map(p => { + return ; + })} + + +
+ )} + + )} + {props.frags.map(f => ( + + ))} + + ); +} diff --git a/packages/app/src/Element/ProxyImg.tsx b/packages/app/src/Element/ProxyImg.tsx index 54384dec..ae6a03ad 100644 --- a/packages/app/src/Element/ProxyImg.tsx +++ b/packages/app/src/Element/ProxyImg.tsx @@ -5,12 +5,13 @@ import { getUrlHostname } from "@/SnortUtils"; interface ProxyImgProps extends React.DetailedHTMLProps, HTMLImageElement> { size?: number; + className?: string; } export const ProxyImg = (props: ProxyImgProps) => { const { proxy } = useImgProxy(); const [loadFailed, setLoadFailed] = useState(false); - const [bypass, setBypass] = useState(false); + const [bypass, setBypass] = useState(CONFIG.bypassImgProxyError); if (loadFailed) { if (bypass) { diff --git a/packages/app/src/Element/User/Avatar.css b/packages/app/src/Element/User/Avatar.css index 214daef7..d92dddaa 100644 --- a/packages/app/src/Element/User/Avatar.css +++ b/packages/app/src/Element/User/Avatar.css @@ -30,6 +30,9 @@ } .avatar .icons { + position: absolute; + top: 0; + right: 0; width: 100%; height: 100%; display: flex; diff --git a/packages/app/src/Element/User/Avatar.tsx b/packages/app/src/Element/User/Avatar.tsx index 0b77eeec..ba52c282 100644 --- a/packages/app/src/Element/User/Avatar.tsx +++ b/packages/app/src/Element/User/Avatar.tsx @@ -1,11 +1,11 @@ import "./Avatar.css"; -import { CSSProperties, ReactNode, useEffect, useState } from "react"; +import { ReactNode, useEffect, useState } from "react"; import type { UserMetadata } from "@snort/system"; import classNames from "classnames"; -import useImgProxy from "@/Hooks/useImgProxy"; import { defaultAvatar, getDisplayName } from "@/SnortUtils"; +import { ProxyImg } from "@/Element/ProxyImg"; interface AvatarProps { pubkey: string; @@ -20,33 +20,27 @@ interface AvatarProps { const Avatar = ({ pubkey, user, size, onClick, image, imageOverlay, icons, className }: AvatarProps) => { const [url, setUrl] = useState(""); - const { proxy } = useImgProxy(); + + useEffect(() => { + setUrl(image ?? user?.picture ?? defaultAvatar(pubkey)); + }, [user, image, pubkey]); const s = size ?? 120; - useEffect(() => { - const url = image ?? user?.picture; - if (url) { - const proxyUrl = proxy(url, s); - setUrl(proxyUrl); - } else { - setUrl(defaultAvatar(pubkey)); - } - }, [user, image]); - - const backgroundImage = `url(${url})`; - const style = { "--img-url": backgroundImage } as CSSProperties; + const style = {} as React.CSSProperties; if (size) { - style.width = `${s}px`; - style.height = `${s}px`; + style.width = `${size}px`; + style.height = `${size}px`; } + const domain = user?.nip05 && user.nip05.split("@")[1]; return (
+ {icons &&
{icons}
} {imageOverlay &&
{imageOverlay}
}
diff --git a/packages/app/src/Pages/DeckLayout.tsx b/packages/app/src/Pages/DeckLayout.tsx index bbbbf0ec..2e610cc3 100644 --- a/packages/app/src/Pages/DeckLayout.tsx +++ b/packages/app/src/Pages/DeckLayout.tsx @@ -1,5 +1,5 @@ import "./Deck.css"; -import { CSSProperties, createContext, useContext, useEffect, useState } from "react"; +import { createContext, useContext, useEffect, useState } from "react"; import { Outlet, useNavigate } from "react-router-dom"; import { FormattedMessage } from "react-intl"; import { NostrLink, TaggedNostrEvent } from "@snort/system";