mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-19 19:46:34 +00:00
use custom skeleton for note
This commit is contained in:
parent
348dc9009c
commit
5d9b440dc8
@ -28,7 +28,6 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.43.9",
|
"react-hook-form": "^7.43.9",
|
||||||
"react-loading-skeleton": "^3.3.1",
|
|
||||||
"react-markdown": "^8.0.7",
|
"react-markdown": "^8.0.7",
|
||||||
"react-virtuoso": "^4.3.5",
|
"react-virtuoso": "^4.3.5",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
|
@ -43,9 +43,6 @@ dependencies:
|
|||||||
react-hook-form:
|
react-hook-form:
|
||||||
specifier: ^7.43.9
|
specifier: ^7.43.9
|
||||||
version: 7.43.9(react@18.2.0)
|
version: 7.43.9(react@18.2.0)
|
||||||
react-loading-skeleton:
|
|
||||||
specifier: ^3.3.1
|
|
||||||
version: 3.3.1(react@18.2.0)
|
|
||||||
react-markdown:
|
react-markdown:
|
||||||
specifier: ^8.0.7
|
specifier: ^8.0.7
|
||||||
version: 8.0.7(@types/react@18.2.6)(react@18.2.0)
|
version: 8.0.7(@types/react@18.2.6)(react@18.2.0)
|
||||||
@ -3947,15 +3944,6 @@ packages:
|
|||||||
{ integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== }
|
{ integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== }
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/react-loading-skeleton@3.3.1(react@18.2.0):
|
|
||||||
resolution:
|
|
||||||
{ integrity: sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA== }
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.8.0'
|
|
||||||
dependencies:
|
|
||||||
react: 18.2.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/react-markdown@8.0.7(@types/react@18.2.6)(react@18.2.0):
|
/react-markdown@8.0.7(@types/react@18.2.6)(react@18.2.0):
|
||||||
resolution:
|
resolution:
|
||||||
{ integrity: sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ== }
|
{ integrity: sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ== }
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Header } from '@lume/app/daily/components/header';
|
import { Header } from '@lume/app/daily/components/header';
|
||||||
import { NoteBase } from '@lume/app/note/components/base';
|
import { NoteBase } from '@lume/app/note/components/base';
|
||||||
import { NoteQuoteRepost } from '@lume/app/note/components/quoteRepost';
|
import { NoteQuoteRepost } from '@lume/app/note/components/quoteRepost';
|
||||||
|
import { NoteSkeleton } from '@lume/app/note/components/skeleton';
|
||||||
import { getNotes } from '@lume/utils/storage';
|
import { getNotes } from '@lume/utils/storage';
|
||||||
|
|
||||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import Skeleton from 'react-loading-skeleton';
|
|
||||||
|
|
||||||
const ITEM_PER_PAGE = 10;
|
const ITEM_PER_PAGE = 10;
|
||||||
const TIME = Math.floor(Date.now() / 1000);
|
const TIME = Math.floor(Date.now() / 1000);
|
||||||
@ -56,7 +56,11 @@ export function Page() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
{status === 'loading' ? (
|
{status === 'loading' ? (
|
||||||
<Skeleton count={5} containerClassName="flex-1" />
|
<div className="px-3 py-1.5">
|
||||||
|
<div className="rounded-md border border-zinc-800 bg-zinc-900 px-3 py-3 shadow-input shadow-black/20">
|
||||||
|
<NoteSkeleton />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
) : status === 'error' ? (
|
) : status === 'error' ? (
|
||||||
<div>{error.message}</div>
|
<div>{error.message}</div>
|
||||||
) : (
|
) : (
|
||||||
@ -95,8 +99,10 @@ export function Page() {
|
|||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
{isFetching && !isFetchingNextPage ? (
|
{isFetching && !isFetchingNextPage ? (
|
||||||
<div className="px-3 py-5">
|
<div className="px-3 py-1.5">
|
||||||
<Skeleton count={3} containerClassName="flex-1" />
|
<div className="rounded-md border border-zinc-800 bg-zinc-900 px-3 py-3 shadow-input shadow-black/20">
|
||||||
|
<NoteSkeleton />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,8 +6,10 @@ import { NoteWrapper } from '@lume/app/note/components/wrapper';
|
|||||||
import { noteParser } from '@lume/utils/parser';
|
import { noteParser } from '@lume/utils/parser';
|
||||||
import { isTagsIncludeID } from '@lume/utils/transform';
|
import { isTagsIncludeID } from '@lume/utils/transform';
|
||||||
|
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const NoteBase = ({ event }: { event: any }) => {
|
export const NoteBase = ({ event }: { event: any }) => {
|
||||||
const content = noteParser(event);
|
const content = useMemo(() => noteParser(event), [event]);
|
||||||
const checkParentID = isTagsIncludeID(event.parent_id, event.tags);
|
const checkParentID = isTagsIncludeID(event.parent_id, event.tags);
|
||||||
|
|
||||||
const href = event.parent_id ? `/app/note?id=${event.parent_id}` : `/app/note?id=${event.event_id}`;
|
const href = event.parent_id ? `/app/note?id=${event.parent_id}` : `/app/note?id=${event.event_id}`;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { NoteContent } from '@lume/app/note/components/content';
|
import { NoteContent } from '@lume/app/note/components/content';
|
||||||
import NoteFile from '@lume/app/note/components/file';
|
import NoteFile from '@lume/app/note/components/file';
|
||||||
|
import { NoteSkeleton } from '@lume/app/note/components/skeleton';
|
||||||
import { NoteDefaultUser } from '@lume/app/note/components/user/default';
|
import { NoteDefaultUser } from '@lume/app/note/components/user/default';
|
||||||
import { NoteWrapper } from '@lume/app/note/components/wrapper';
|
import { NoteWrapper } from '@lume/app/note/components/wrapper';
|
||||||
import { RelayContext } from '@lume/shared/relayProvider';
|
import { RelayContext } from '@lume/shared/relayProvider';
|
||||||
@ -7,7 +8,6 @@ import { READONLY_RELAYS } from '@lume/stores/constants';
|
|||||||
import { noteParser } from '@lume/utils/parser';
|
import { noteParser } from '@lume/utils/parser';
|
||||||
|
|
||||||
import { memo, useContext } from 'react';
|
import { memo, useContext } from 'react';
|
||||||
import Skeleton from 'react-loading-skeleton';
|
|
||||||
import useSWRSubscription from 'swr/subscription';
|
import useSWRSubscription from 'swr/subscription';
|
||||||
|
|
||||||
export const MentionNote = memo(function MentionNote({ id }: { id: string }) {
|
export const MentionNote = memo(function MentionNote({ id }: { id: string }) {
|
||||||
@ -50,7 +50,7 @@ export const MentionNote = memo(function MentionNote({ id }: { id: string }) {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Skeleton baseColor="#27272a" containerClassName="flex-1" />
|
<NoteSkeleton />
|
||||||
)}
|
)}
|
||||||
</NoteWrapper>
|
</NoteWrapper>
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { NoteContent } from '@lume/app/note/components/content';
|
import { NoteContent } from '@lume/app/note/components/content';
|
||||||
import NoteFile from '@lume/app/note/components/file';
|
import NoteFile from '@lume/app/note/components/file';
|
||||||
import NoteMetadata from '@lume/app/note/components/metadata';
|
import NoteMetadata from '@lume/app/note/components/metadata';
|
||||||
|
import { NoteSkeleton } from '@lume/app/note/components/skeleton';
|
||||||
import { NoteDefaultUser } from '@lume/app/note/components/user/default';
|
import { NoteDefaultUser } from '@lume/app/note/components/user/default';
|
||||||
import { RelayContext } from '@lume/shared/relayProvider';
|
import { RelayContext } from '@lume/shared/relayProvider';
|
||||||
import { READONLY_RELAYS } from '@lume/stores/constants';
|
import { READONLY_RELAYS } from '@lume/stores/constants';
|
||||||
import { noteParser } from '@lume/utils/parser';
|
import { noteParser } from '@lume/utils/parser';
|
||||||
|
|
||||||
import { memo, useContext } from 'react';
|
import { memo, useContext } from 'react';
|
||||||
import Skeleton from 'react-loading-skeleton';
|
|
||||||
import useSWRSubscription from 'swr/subscription';
|
import useSWRSubscription from 'swr/subscription';
|
||||||
|
|
||||||
export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
|
export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
|
||||||
@ -52,7 +52,7 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Skeleton baseColor="#27272a" containerClassName="flex-1" />
|
<NoteSkeleton />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { NoteContent } from '@lume/app/note/components/content';
|
import { NoteContent } from '@lume/app/note/components/content';
|
||||||
import NoteFile from '@lume/app/note/components/file';
|
import NoteFile from '@lume/app/note/components/file';
|
||||||
import NoteMetadata from '@lume/app/note/components/metadata';
|
import NoteMetadata from '@lume/app/note/components/metadata';
|
||||||
|
import { NoteSkeleton } from '@lume/app/note/components/skeleton';
|
||||||
import { NoteDefaultUser } from '@lume/app/note/components/user/default';
|
import { NoteDefaultUser } from '@lume/app/note/components/user/default';
|
||||||
import { RelayContext } from '@lume/shared/relayProvider';
|
import { RelayContext } from '@lume/shared/relayProvider';
|
||||||
import { READONLY_RELAYS } from '@lume/stores/constants';
|
import { READONLY_RELAYS } from '@lume/stores/constants';
|
||||||
import { noteParser } from '@lume/utils/parser';
|
import { noteParser } from '@lume/utils/parser';
|
||||||
|
|
||||||
import { memo, useContext } from 'react';
|
import { memo, useContext } from 'react';
|
||||||
import Skeleton from 'react-loading-skeleton';
|
|
||||||
import useSWRSubscription from 'swr/subscription';
|
import useSWRSubscription from 'swr/subscription';
|
||||||
import { navigate } from 'vite-plugin-ssr/client/router';
|
import { navigate } from 'vite-plugin-ssr/client/router';
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ export const RootNote = memo(function RootNote({ id, fallback }: { id: string; f
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Skeleton baseColor="#27272a" containerClassName="flex-1" />
|
<NoteSkeleton />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
20
src/app/note/components/skeleton.tsx
Normal file
20
src/app/note/components/skeleton.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export const NoteSkeleton = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex h-min flex-col">
|
||||||
|
<div className="flex items-center gap-2.5">
|
||||||
|
<div className="relative h-9 w-9 shrink overflow-hidden rounded-md bg-zinc-700" />
|
||||||
|
<div className="flex flex-col gap-0.5">
|
||||||
|
<div className="h-3 w-20 rounded-sm bg-zinc-700" />
|
||||||
|
<div className="h-2 w-12 rounded-sm bg-zinc-700" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-3 animate-pulse pl-[46px]">
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<div className="h-4 w-full rounded-sm bg-zinc-700" />
|
||||||
|
<div className="h-4 w-2/3 rounded-sm bg-zinc-700" />
|
||||||
|
<div className="h-4 w-1/2 rounded-sm bg-zinc-700" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -23,7 +23,7 @@ export const NoteDefaultUser = ({ pubkey, time }: { pubkey: string; time: number
|
|||||||
<div className="flex w-full flex-1 items-start justify-between">
|
<div className="flex w-full flex-1 items-start justify-between">
|
||||||
<div className="flex flex-col gap-0.5">
|
<div className="flex flex-col gap-0.5">
|
||||||
<h5 className="text-sm font-semibold leading-none group-hover:underline">
|
<h5 className="text-sm font-semibold leading-none group-hover:underline">
|
||||||
{user?.display_name || user?.name || <div className="h-3 w-20 animate-pulse rounded-sm bg-zinc-800"></div>}
|
{user?.display_name || user?.name || <div className="h-3 w-20 animate-pulse rounded-sm bg-zinc-700"></div>}
|
||||||
</h5>
|
</h5>
|
||||||
<div className="flex items-baseline gap-1.5 text-sm leading-none text-zinc-500">
|
<div className="flex items-baseline gap-1.5 text-sm leading-none text-zinc-500">
|
||||||
<span>{user?.nip05 || shortenKey(pubkey)}</span>
|
<span>{user?.nip05 || shortenKey(pubkey)}</span>
|
||||||
|
@ -4,7 +4,6 @@ import { useProfile } from '@lume/utils/hooks/useProfile';
|
|||||||
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
import Skeleton from 'react-loading-skeleton';
|
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ export const NoteRepostUser = ({ pubkey, time }: { pubkey: string; time: number
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-baseline gap-1.5 text-sm">
|
<div className="flex items-baseline gap-1.5 text-sm">
|
||||||
<h5 className="font-semibold leading-tight group-hover:underline">
|
<h5 className="font-semibold leading-tight group-hover:underline">
|
||||||
{user?.display_name || user?.name || <Skeleton />}
|
{user?.display_name || user?.name || <div className="h-3 w-20 animate-pulse rounded-sm bg-zinc-700"></div>}
|
||||||
<span className="bg-gradient-to-r from-fuchsia-300 via-orange-100 to-amber-300 bg-clip-text text-transparent">
|
<span className="bg-gradient-to-r from-fuchsia-300 via-orange-100 to-amber-300 bg-clip-text text-transparent">
|
||||||
{' '}
|
{' '}
|
||||||
reposted
|
reposted
|
||||||
|
Loading…
Reference in New Issue
Block a user