From 6b030f2902d30fcff47bdfd23662d2d210e2afd7 Mon Sep 17 00:00:00 2001 From: reya Date: Wed, 8 Nov 2023 08:21:52 +0700 Subject: [PATCH] polish --- src/app.css | 6 +- src/app/new/components/mentionPopupItem.tsx | 4 +- src/shared/image.tsx | 32 ---- src/shared/notes/article.tsx | 6 +- src/shared/notes/index.ts | 1 - src/shared/notes/preview/image.tsx | 4 +- src/shared/notes/preview/link.tsx | 2 +- src/shared/notes/replies/item.tsx | 48 +++--- src/shared/notes/replies/list.tsx | 1 + src/shared/notes/replies/sub.tsx | 2 +- src/shared/notes/stats.tsx | 85 ----------- src/shared/user.tsx | 2 +- src/shared/userProfile.tsx | 14 +- src/shared/widgets/newsfeed.tsx | 4 +- src/shared/widgets/nostrBandUserProfile.tsx | 12 +- src/shared/widgets/notification.tsx | 4 +- src/stores/constants.ts | 2 +- src/utils/parser.ts | 153 -------------------- 18 files changed, 55 insertions(+), 327 deletions(-) delete mode 100644 src/shared/image.tsx delete mode 100644 src/shared/notes/stats.tsx delete mode 100644 src/utils/parser.ts diff --git a/src/app.css b/src/app.css index a9a0e5fc..d7f5d15b 100644 --- a/src/app.css +++ b/src/app.css @@ -114,6 +114,9 @@ input::-ms-clear { inset: 20px 20px auto auto; cursor: zoom-out; z-index: 1; + display: flex; + align-items: center; + justify-content: center; } [data-rmiz-content="found"] img, @@ -153,7 +156,8 @@ input::-ms-clear { } [data-rmiz-modal-overlay="visible"] { - background-color: rgba(255, 255, 255, 1); + background-color: rgba(255, 255, 255, 0.5); + backdrop-filter: blur(4px); } [data-rmiz-modal-content] { diff --git a/src/app/new/components/mentionPopupItem.tsx b/src/app/new/components/mentionPopupItem.tsx index c2fa6614..d4e8f95d 100644 --- a/src/app/new/components/mentionPopupItem.tsx +++ b/src/app/new/components/mentionPopupItem.tsx @@ -1,5 +1,3 @@ -import { Image } from '@shared/image'; - import { useProfile } from '@utils/hooks/useProfile'; import { displayNpub } from '@utils/shortenKey'; @@ -20,7 +18,7 @@ export function MentionPopupItem({ pubkey, embed }: { pubkey: string; embed?: st return (
- {pubkey}) { - const [isError, setIsError] = useState(false); - - if (isError || !src) { - const svgURI = - 'data:image/svg+xml;utf8,' + encodeURIComponent(minidenticon(props.alt, 90, 50)); - return ( - {props.alt} - ); - } - - return ( - { - currentTarget.onerror = null; - setIsError(true); - }} - loading="lazy" - decoding="async" - alt="lume default img" - style={{ contentVisibility: 'auto' }} - /> - ); -}); diff --git a/src/shared/notes/article.tsx b/src/shared/notes/article.tsx index 56d16760..1f2126bd 100644 --- a/src/shared/notes/article.tsx +++ b/src/shared/notes/article.tsx @@ -35,11 +35,11 @@ export function ArticleNote({ event }: { event: NDKEvent }) {
-
+
{metadata.image && ( )} -
+
{metadata.title}
diff --git a/src/shared/notes/index.ts b/src/shared/notes/index.ts index 83e74953..37aad1d6 100644 --- a/src/shared/notes/index.ts +++ b/src/shared/notes/index.ts @@ -6,7 +6,6 @@ export * from './child'; export * from './notify'; export * from './unknown'; export * from './skeleton'; -export * from './stats'; export * from './actions'; export * from './actions/reaction'; export * from './actions/reply'; diff --git a/src/shared/notes/preview/image.tsx b/src/shared/notes/preview/image.tsx index 1e356361..5ce7f1df 100644 --- a/src/shared/notes/preview/image.tsx +++ b/src/shared/notes/preview/image.tsx @@ -3,7 +3,7 @@ import { download } from '@tauri-apps/plugin-upload'; import { SyntheticEvent } from 'react'; import Zoom from 'react-medium-image-zoom'; -import { DownloadIcon } from '@shared/icons'; +import { CancelIcon, DownloadIcon } from '@shared/icons'; export function ImagePreview({ url }: { url: string }) { const downloadImage = async (url: string) => { @@ -17,7 +17,7 @@ export function ImagePreview({ url }: { url: string }) { }; return ( - + }>
{url} ) : null}
diff --git a/src/shared/notes/replies/item.tsx b/src/shared/notes/replies/item.tsx index e0d152ea..9f6fc08c 100644 --- a/src/shared/notes/replies/item.tsx +++ b/src/shared/notes/replies/item.tsx @@ -12,25 +12,15 @@ export function Reply({ event, root }: { event: NDKEventWithReplies; root?: stri const [open, setOpen] = useState(false); return ( -
-
- - -
- -
-
-
- - {event.replies?.length > 0 ? ( -
+ +
+
+ + +
+ {event.replies?.length > 0 ? ( -
+
@@ -39,13 +29,23 @@ export function Reply({ event, root }: { event: NDKEventWithReplies; root?: stri (event.replies?.length === 1 ? 'reply' : 'replies')}
- - {event.replies?.map((sub) => )} - -
+ ) : null} + +
+
+
+ {event.replies?.length > 0 ? ( + + {event.replies?.map((sub) => )} + ) : null} - +
-
+
); } diff --git a/src/shared/notes/replies/list.tsx b/src/shared/notes/replies/list.tsx index 2ec97e7e..ec16edd8 100644 --- a/src/shared/notes/replies/list.tsx +++ b/src/shared/notes/replies/list.tsx @@ -48,6 +48,7 @@ export function ReplyList({ eventId }: { eventId: string }) { return (
+

Replies

{data?.length === 0 ? (
diff --git a/src/shared/notes/replies/sub.tsx b/src/shared/notes/replies/sub.tsx index dcb921b0..7e3117ae 100644 --- a/src/shared/notes/replies/sub.tsx +++ b/src/shared/notes/replies/sub.tsx @@ -5,7 +5,7 @@ import { User } from '@shared/user'; export function SubReply({ event }: { event: NDKEvent }) { return ( -
+
diff --git a/src/shared/notes/stats.tsx b/src/shared/notes/stats.tsx deleted file mode 100644 index 147a06c5..00000000 --- a/src/shared/notes/stats.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk'; -import { useQuery } from '@tanstack/react-query'; -import { decode } from 'light-bolt11-decoder'; - -import { useNDK } from '@libs/ndk/provider'; - -import { LoaderIcon } from '@shared/icons'; - -import { compactNumber } from '@utils/number'; - -export function NoteStats({ id }: { id: string }) { - const { ndk } = useNDK(); - const { status, data } = useQuery({ - queryKey: ['note-stats', id], - queryFn: async () => { - let reactions = 0; - let reposts = 0; - let zaps = 0; - - const filter: NDKFilter = { - '#e': [id], - kinds: [6, 7, 9735], - }; - - const events = await ndk.fetchEvents(filter); - events.forEach((event: NDKEvent) => { - switch (event.kind) { - case 6: - reposts += 1; - break; - case 7: - reactions += 1; - break; - case 9735: { - const bolt11 = event.tags.find((tag) => tag[0] === 'bolt11')[1]; - if (bolt11) { - const decoded = decode(bolt11); - const amount = decoded.sections.find((item) => item.name === 'amount'); - const sats = amount.value / 1000; - zaps += sats; - } - break; - } - default: - break; - } - }); - - return { reposts, reactions, zaps }; - }, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - }); - - if (status === 'pending') { - return ( -
- -
- ); - } - - return ( -
-
-
- {compactNumber.format(data.reactions)} -
-
Reactions
-
-
-
- {compactNumber.format(data.reposts)} -
-
Reposts
-
-
-
- {compactNumber.format(data.zaps)} -
-
Zaps
-
-
- ); -} diff --git a/src/shared/user.tsx b/src/shared/user.tsx index 73bc25e0..d774981c 100644 --- a/src/shared/user.tsx +++ b/src/shared/user.tsx @@ -298,7 +298,7 @@ export const User = memo(function User({ alt={pubkey} loading="lazy" decoding="async" - className="h-10 w-10 rounded-lg" + className="h-10 w-10 rounded-lg object-cover" /> {pubkey}
{followed ? ( @@ -102,7 +99,7 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
-
+
{user?.name || user?.display_name || user?.displayName || 'Anon'} @@ -119,11 +116,8 @@ export function UserProfile({ pubkey }: { pubkey: string }) { )}
-
-

- {user?.about} -

- +
+ {user?.about}
diff --git a/src/shared/widgets/newsfeed.tsx b/src/shared/widgets/newsfeed.tsx index f6d3f50c..1ae017a3 100644 --- a/src/shared/widgets/newsfeed.tsx +++ b/src/shared/widgets/newsfeed.tsx @@ -17,6 +17,8 @@ import { TitleBar } from '@shared/titleBar'; import { WidgetWrapper } from '@shared/widgets'; import { LiveUpdater } from '@shared/widgets'; +import { FETCH_LIMIT } from '@stores/constants'; + export function NewsfeedWidget() { const { db } = useStorage(); const { relayUrls, ndk, fetcher } = useNDK(); @@ -40,7 +42,7 @@ export function NewsfeedWidget() { kinds: [NDKKind.Text, NDKKind.Repost], authors: db.account.circles, }, - 20, + FETCH_LIMIT, { asOf: pageParam === 0 ? undefined : pageParam, abortSignal: signal } ); diff --git a/src/shared/widgets/nostrBandUserProfile.tsx b/src/shared/widgets/nostrBandUserProfile.tsx index 29a7365d..2cab6431 100644 --- a/src/shared/widgets/nostrBandUserProfile.tsx +++ b/src/shared/widgets/nostrBandUserProfile.tsx @@ -7,7 +7,6 @@ import { useNDK } from '@libs/ndk/provider'; import { useStorage } from '@libs/storage/provider'; import { FollowIcon, UnfollowIcon } from '@shared/icons'; -import { Image } from '@shared/image'; import { compactNumber } from '@utils/number'; import { shortenKey } from '@utils/shortenKey'; @@ -95,8 +94,9 @@ export function NostrBandUserProfile({ data }: { data: Profile }) {
- {data.pubkey}
@@ -128,12 +128,10 @@ export function NostrBandUserProfile({ data }: { data: Profile }) { )}
-
-

- {profile.about || profile.bio} -

+
+ {profile.about || profile.bio}
-
+
{status === 'pending' ? (

Loading...

) : ( diff --git a/src/shared/widgets/notification.tsx b/src/shared/widgets/notification.tsx index ac343e62..e002f474 100644 --- a/src/shared/widgets/notification.tsx +++ b/src/shared/widgets/notification.tsx @@ -11,6 +11,8 @@ import { MemoizedNotifyNote, NoteSkeleton } from '@shared/notes'; import { TitleBar } from '@shared/titleBar'; import { WidgetWrapper } from '@shared/widgets'; +import { FETCH_LIMIT } from '@stores/constants'; + import { useNostr } from '@utils/hooks/useNostr'; import { sendNativeNotification } from '@utils/notification'; @@ -37,7 +39,7 @@ export function NotificationWidget() { kinds: [NDKKind.Text, NDKKind.Repost, NDKKind.Reaction, NDKKind.Zap], '#p': [db.account.pubkey], }, - 20, + FETCH_LIMIT, { asOf: pageParam === 0 ? undefined : pageParam, abortSignal: signal } ); diff --git a/src/stores/constants.ts b/src/stores/constants.ts index 7b22c168..34412fc0 100644 --- a/src/stores/constants.ts +++ b/src/stores/constants.ts @@ -8,7 +8,7 @@ export const FULL_RELAYS = [ 'wss://nostr.mutinywallet.com', ]; -export const FETCH_LIMIT = 50; +export const FETCH_LIMIT = 20; export const WidgetKinds = { local: { diff --git a/src/utils/parser.ts b/src/utils/parser.ts deleted file mode 100644 index 72522223..00000000 --- a/src/utils/parser.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { nip19 } from 'nostr-tools'; -import { - AddressPointer, - EventPointer, - ProfilePointer, -} from 'nostr-tools/lib/types/nip19'; - -import { RichContent } from '@utils/types'; - -function isURL(string: string) { - try { - const url = new URL(string); - if (url.protocol.length > 0) { - if (url.protocol === 'https:' || url.protocol === 'http:') { - return true; - } else { - return false; - } - } - return true; - } catch (e) { - return false; - } -} - -export function parser(content: string) { - const richContent: RichContent = { - parsed: null, - images: [], - videos: [], - links: [], - notes: [], - }; - - const parsed = content - .trim() - .split(/(\s+)/) - .map((word) => { - // url - if (isURL(word)) { - const url = new URL(word); - url.search = ''; - - if (url.pathname.match(/\.(jpg|jpeg|gif|png|webp|avif|tiff)$/)) { - // image url - richContent.images.push(word); - // remove url from original content - return word.replace(word, ''); - } - - if (url.pathname.match(/\.(mp4|mov|webm|wmv|flv|mts|avi|ogv|mkv|mp3|m3u8)$/)) { - // video url - richContent.videos.push(word); - // remove url from original content - return word.replace(word, ''); - } - - // normal url - if (richContent.links.length < 1) { - richContent.links.push(url.toString()); - } - } - - // hashtag - if (word.startsWith('#') && word.length > 1) { - return word.replace(word, ``); - } - - // boost - if (word.startsWith('$prism') && word.length > 1) { - return word.replace(word, ``); - } - - // nostr account references (depreciated) - if (word.startsWith('@npub1')) { - const npub = word.replace('@', '').replace(/[^a-zA-Z0-9 ]/g, ''); - try { - const pubkey = nip19.decode(npub).data as string; - return word.replace(word, ``); - } catch { - return word; - } - } - - // nostr account references - if (word.startsWith('nostr:npub1') || word.startsWith('npub1')) { - const npub = word.replace('nostr:', '').replace(/[^a-zA-Z0-9 ]/g, ''); - try { - const pubkey = nip19.decode(npub).data as string; - return word.replace(word, ``); - } catch { - return word; - } - } - - // nostr profile references - if (word.startsWith('nostr:nprofile1') || word.startsWith('nprofile1')) { - const nprofile = word.replace('nostr:', '').replace(/[^a-zA-Z0-9 ]/g, ''); - try { - const decoded = nip19.decode(nprofile).data as ProfilePointer; - return word.replace(word, ``); - } catch { - return word; - } - } - - // nostr address references - if (word.startsWith('nostr:naddr1') || word.startsWith('naddr1')) { - const naddr = word.replace('nostr:', '').replace(/[^a-zA-Z0-9 ]/g, ''); - try { - const decoded = nip19.decode(naddr).data as AddressPointer; - return word.replace(word, ``); - } catch { - return word; - } - } - - // lightning invoice - if (word.startsWith('lnbc') && word.length > 60) { - return word.replace(word, ``); - } - - // nostr note references - if (word.startsWith('nostr:note1') || word.startsWith('note1')) { - const note = word.replace('nostr:', '').replace(/[^a-zA-Z0-9 ]/g, ''); - try { - const eventId = nip19.decode(note).data as string; - richContent.notes.push(eventId); - return word.replace(word, ''); - } catch { - return word; - } - } - - // nostr event references - if (word.startsWith('nostr:nevent1') || word.startsWith('nevent1')) { - const nevent = word.replace('nostr:', '').replace(/[^a-zA-Z0-9 ]/g, ''); - try { - const decoded = nip19.decode(nevent).data as EventPointer; - richContent.notes.push(decoded.id); - return word.replace(word, ''); - } catch { - return word; - } - } - - return word; - }); - - // update content with parsed version - richContent.parsed = parsed.join(' ').trim(); - return richContent; -}