diff --git a/src/app/explore/channels/page.tsx b/src/app/explore/channels/page.tsx
new file mode 100644
index 00000000..135d8fe0
--- /dev/null
+++ b/src/app/explore/channels/page.tsx
@@ -0,0 +1,67 @@
+'use client';
+
+import { BrowseChannelItem } from '@components/channels/browseChannelItem';
+
+import { getChannels } from '@utils/storage';
+
+import { Suspense, useCallback, useEffect, useRef, useState } from 'react';
+import { VirtuosoGrid } from 'react-virtuoso';
+
+export default function Page() {
+ const [data, setData] = useState([]);
+
+ const virtuosoRef = useRef(null);
+ const limit = useRef(20);
+ const offset = useRef(0);
+
+ const itemContent: any = useCallback(
+ (index: string | number) => {
+ return ;
+ },
+ [data]
+ );
+
+ const computeItemKey = useCallback(
+ (index: string | number) => {
+ return data[index].event_id;
+ },
+ [data]
+ );
+
+ const initialData = useCallback(async () => {
+ const result: any = await getChannels(limit.current, offset.current);
+ console.log(result);
+ setData((data) => [...data, ...result]);
+ }, [setData]);
+
+ const loadMore = useCallback(async () => {
+ offset.current += limit.current;
+ // query next page
+ const result: any = await getChannels(limit.current, offset.current);
+ setData((data) => [...data, ...result]);
+ }, [setData]);
+
+ useEffect(() => {
+ initialData().catch(console.error);
+ }, [initialData]);
+
+ return (
+
+
+ Loading...>}>
+
+
+
+
+ );
+}
diff --git a/src/app/explore/layout.tsx b/src/app/explore/layout.tsx
new file mode 100644
index 00000000..99e35bb1
--- /dev/null
+++ b/src/app/explore/layout.tsx
@@ -0,0 +1,23 @@
+import AppHeader from '@components/appHeader';
+import MultiAccounts from '@components/multiAccounts';
+
+export default function NostrLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+ );
+}
diff --git a/src/app/nostr/channels/page.tsx b/src/app/nostr/channels/page.tsx
deleted file mode 100644
index 5dc58d62..00000000
--- a/src/app/nostr/channels/page.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-'use client';
-
-import { BrowseChannelItem } from '@components/channels/browseChannelItem';
-
-import { getChannels } from '@utils/storage';
-
-import { useEffect, useState } from 'react';
-
-export default function Page() {
- const [list, setList] = useState([]);
-
- useEffect(() => {
- getChannels(100, 0)
- .then((res) => setList(res))
- .catch(console.error);
- }, []);
-
- return (
-
- {list.map((channel) => (
-
- ))}
-
- );
-}
diff --git a/src/components/channels/browseChannelItem.tsx b/src/components/channels/browseChannelItem.tsx
index 367f21f2..cd7f4d94 100644
--- a/src/components/channels/browseChannelItem.tsx
+++ b/src/components/channels/browseChannelItem.tsx
@@ -1,6 +1,6 @@
import { ImageWithFallback } from '@components/imageWithFallback';
-import { DEFAULT_AVATAR } from '@stores/constants';
+import { DEFAULT_AVATAR, DEFAULT_CHANNEL_BANNER } from '@stores/constants';
import { useChannelMetadata } from '@utils/hooks/useChannelMetadata';
@@ -19,26 +19,32 @@ export const BrowseChannelItem = ({ data }: { data: any }) => {
);
return (
- openChannel(data.event_id)}
- className="group relative flex items-center gap-2 border-b border-zinc-800 px-3 py-2.5 hover:bg-black/20"
- >
-
-
+
+
-
- {channel?.name}
- {channel?.about}
-
-
-
+
+
+
{channel?.name}
+
+
{channel?.about}
);
diff --git a/src/components/channels/channelList.tsx b/src/components/channels/channelList.tsx
index 01e260c3..3d5b08d9 100644
--- a/src/components/channels/channelList.tsx
+++ b/src/components/channels/channelList.tsx
@@ -11,7 +11,7 @@ export default function ChannelList() {
return (
diff --git a/src/stores/constants.tsx b/src/stores/constants.tsx
index f4ce04e7..103d9a8e 100644
--- a/src/stores/constants.tsx
+++ b/src/stores/constants.tsx
@@ -1,2 +1,4 @@
export const APP_VERSION = '0.2.5';
export const DEFAULT_AVATAR = 'https://void.cat/d/KmypFh2fBdYCEvyJrPiN89.webp';
+export const DEFAULT_CHANNEL_BANNER =
+ 'https://bafybeiacwit7hjmdefqggxqtgh6ht5dhth7ndptwn2msl5kpkodudsr7py.ipfs.w3s.link/banner-1.jpg';