From a2e32474324793b7d54d6df3985a146acf4415e0 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 30 Sep 2023 15:12:33 +0700 Subject: [PATCH] wip --- package.json | 2 +- pnpm-lock.yaml | 81 +++++++---------- src/app.tsx | 61 ++++++++----- src/app/browse/index.tsx | 43 --------- src/app/browse/relays.tsx | 12 --- .../{browse => explore}/components/edge.tsx | 0 .../components/groupTitle.tsx | 0 .../{browse => explore}/components/line.tsx | 0 .../components/userGroupNode.tsx | 2 +- .../components/userLatestPosts.tsx | 0 .../components/userNode.tsx | 0 .../components/userWithDrawer.tsx | 0 .../{browse/users.tsx => explore/index.tsx} | 55 ++++++------ src/app/relays/components/relayList.tsx | 89 +++++++++++++++++++ src/app/relays/components/userRelay.tsx | 46 ++++++++++ src/app/relays/index.tsx | 16 ++++ src/app/relays/relay.tsx | 19 ++++ src/app/space/components/toggle.tsx | 29 +++--- src/shared/icons/handArrowDown.tsx | 29 ++++++ src/shared/icons/index.ts | 1 + src/shared/navigation.tsx | 21 ++++- src/shared/notes/kinds/file.tsx | 19 ++-- src/shared/notes/preview/image.tsx | 6 +- src/shared/notes/preview/video.tsx | 29 +++--- src/shared/user.tsx | 25 +++++- src/shared/widgets/eventLoader.tsx | 2 +- src/utils/hooks/useNostr.ts | 26 ++++++ 27 files changed, 414 insertions(+), 199 deletions(-) delete mode 100644 src/app/browse/index.tsx delete mode 100644 src/app/browse/relays.tsx rename src/app/{browse => explore}/components/edge.tsx (100%) rename src/app/{browse => explore}/components/groupTitle.tsx (100%) rename src/app/{browse => explore}/components/line.tsx (100%) rename src/app/{browse => explore}/components/userGroupNode.tsx (92%) rename src/app/{browse => explore}/components/userLatestPosts.tsx (100%) rename src/app/{browse => explore}/components/userNode.tsx (100%) rename src/app/{browse => explore}/components/userWithDrawer.tsx (100%) rename src/app/{browse/users.tsx => explore/index.tsx} (71%) create mode 100644 src/app/relays/components/relayList.tsx create mode 100644 src/app/relays/components/userRelay.tsx create mode 100644 src/app/relays/index.tsx create mode 100644 src/app/relays/relay.tsx create mode 100644 src/shared/icons/handArrowDown.tsx diff --git a/package.json b/package.json index 1d815f60..2f66ea30 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@tiptap/react": "^2.1.11", "@tiptap/starter-kit": "^2.1.11", "@tiptap/suggestion": "^2.1.11", + "@vidstack/react": "^1.0.2", "dayjs": "^1.11.10", "destr": "^2.0.1", "html-to-text": "^9.0.5", @@ -55,7 +56,6 @@ "react-dom": "^18.2.0", "react-hook-form": "^7.46.2", "react-markdown": "^8.0.7", - "react-player": "^2.13.0", "react-router-dom": "^6.16.0", "react-textarea-autosize": "^8.5.3", "reactflow": "^11.9.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81bd9dd9..4428170f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,6 +71,9 @@ dependencies: '@tiptap/suggestion': specifier: ^2.1.11 version: 2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.11) + '@vidstack/react': + specifier: ^1.0.2 + version: 1.0.2(@types/react@18.2.23)(react@18.2.0) dayjs: specifier: ^1.11.10 version: 1.11.10 @@ -116,9 +119,6 @@ dependencies: react-markdown: specifier: ^8.0.7 version: 8.0.7(@types/react@18.2.23)(react@18.2.0) - react-player: - specifier: ^2.13.0 - version: 2.13.0(react@18.2.0) react-router-dom: specifier: ^6.16.0 version: 6.16.0(react-dom@18.2.0)(react@18.2.0) @@ -133,16 +133,16 @@ dependencies: version: 3.0.1 tauri-plugin-sql-api: specifier: github:tauri-apps/tauri-plugin-sql#v1 - version: github.com/tauri-apps/tauri-plugin-sql/533198dd3b6cfca36d876918d22efcdaac43065a + version: github.com/tauri-apps/tauri-plugin-sql/1c79471feb06366fe1c11cb1cb6c67bcdb80c215 tauri-plugin-store-api: specifier: github:tauri-apps/tauri-plugin-store#v1 - version: github.com/tauri-apps/tauri-plugin-store/66e06b7830037fdae0b42b5499e23334eaf4e017 + version: github.com/tauri-apps/tauri-plugin-store/1a741b721ed1eae0de0d811ecfe86fc6ad54fb73 tauri-plugin-stronghold-api: specifier: github:tauri-apps/tauri-plugin-stronghold#v1 - version: github.com/tauri-apps/tauri-plugin-stronghold/4684fed1f5e7eb01885e40114accdcecb61962ed + version: github.com/tauri-apps/tauri-plugin-stronghold/d87b778f48ee12435efcf3f82d2e5efbb9541759 tauri-plugin-upload-api: specifier: github:tauri-apps/tauri-plugin-upload#v1 - version: github.com/tauri-apps/tauri-plugin-upload/40c0bc302a9dd8304762951e450ee84d53c2037b + version: github.com/tauri-apps/tauri-plugin-upload/5348082f7436b01f0b5c08d6ddfc4f760abbac7e tippy.js: specifier: ^6.3.7 version: 6.3.7 @@ -1892,11 +1892,6 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false - /@tauri-apps/api@1.4.0: - resolution: {integrity: sha512-Jd6HPoTM1PZSFIzq7FB8VmMu3qSSyo/3lSwLpoapW+lQ41CL5Dow2KryLg+gyazA/58DRWI9vu/XpEeHK4uMdw==} - engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} - dev: false - /@tauri-apps/api@1.5.0: resolution: {integrity: sha512-yQY9wpVNuiYhLLuyDlu1nBpqJELT1fGp7OctN4rW9I2W1T2p7A3tqPxsEzQprEwneQRBAlPM9vC8NsnMbct+pg==} engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} @@ -2708,6 +2703,18 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@vidstack/react@1.0.2(@types/react@18.2.23)(react@18.2.0): + resolution: {integrity: sha512-ZBTaEFtxmaFX/oB5I9o8qvoQ39jmwTySFxsFfBN7tkcWxKdTOUhwlIgIlFM5H/alJ/qxw13AZvxK2MW6q+le3g==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': ^18.0.0 + react: ^18.0.0 + dependencies: + '@types/react': 18.2.23 + media-captions: 1.0.0 + react: 18.2.0 + dev: false + /@vitejs/plugin-react-swc@3.4.0(vite@4.4.9): resolution: {integrity: sha512-m7UaA4Uvz82N/0EOVpZL4XsFIakRqrFKeSNxa1FBLSXGvWrWRBwmZb4qxk+ZIVAZcW3c3dn5YosomDgx62XWcQ==} peerDependencies: @@ -4460,10 +4467,6 @@ packages: wrap-ansi: 8.1.0 dev: true - /load-script@1.0.0: - resolution: {integrity: sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==} - dev: false - /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -4674,8 +4677,9 @@ packages: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} dev: false - /memoize-one@5.2.1: - resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + /media-captions@1.0.0: + resolution: {integrity: sha512-605d9sXW+DtJBNzzfL4N6NpOIjigN+kpzS+V1QaCiNNPB7G015/peyw6wfv9iCp8GAP6R5NPyAICZKeuqWPAQQ==} + engines: {node: '>=16'} dev: false /merge-stream@2.0.0: @@ -5612,10 +5616,6 @@ packages: scheduler: 0.23.0 dev: false - /react-fast-compare@3.2.2: - resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} - dev: false - /react-hook-form@7.46.2(react@18.2.0): resolution: {integrity: sha512-x1DWmHQchV7x2Rq9l99M/cQHC8JGchAnw9Z0uTz5KrPa0bTl/Inm1NR7ceOARfIrkNuQNAhuSuZPYa6k7QYn3Q==} engines: {node: '>=12.22.0'} @@ -5659,19 +5659,6 @@ packages: - supports-color dev: false - /react-player@2.13.0(react@18.2.0): - resolution: {integrity: sha512-gkY7ZdbVFztlKFFhCPcnDrFQm+L399b8fhWsKatZ+b2wpKJwfUHBXQFMRxqYQGT0ic1/wQ7D7EZEWy7ZBqk2pw==} - peerDependencies: - react: '>=16.6.0' - dependencies: - deepmerge: 4.3.1 - load-script: 1.0.0 - memoize-one: 5.2.1 - prop-types: 15.8.1 - react: 18.2.0 - react-fast-compare: 3.2.2 - dev: false - /react-remove-scroll-bar@2.3.4(@types/react@18.2.23)(react@18.2.0): resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} engines: {node: '>=10'} @@ -6758,34 +6745,34 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: false - github.com/tauri-apps/tauri-plugin-sql/533198dd3b6cfca36d876918d22efcdaac43065a: - resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-sql/tar.gz/533198dd3b6cfca36d876918d22efcdaac43065a} + github.com/tauri-apps/tauri-plugin-sql/1c79471feb06366fe1c11cb1cb6c67bcdb80c215: + resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-sql/tar.gz/1c79471feb06366fe1c11cb1cb6c67bcdb80c215} name: tauri-plugin-sql-api version: 0.0.0 dependencies: - '@tauri-apps/api': 1.4.0 + '@tauri-apps/api': 1.5.0 dev: false - github.com/tauri-apps/tauri-plugin-store/66e06b7830037fdae0b42b5499e23334eaf4e017: - resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-store/tar.gz/66e06b7830037fdae0b42b5499e23334eaf4e017} + github.com/tauri-apps/tauri-plugin-store/1a741b721ed1eae0de0d811ecfe86fc6ad54fb73: + resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-store/tar.gz/1a741b721ed1eae0de0d811ecfe86fc6ad54fb73} name: tauri-plugin-store-api version: 0.0.0 dependencies: - '@tauri-apps/api': 1.4.0 + '@tauri-apps/api': 1.5.0 dev: false - github.com/tauri-apps/tauri-plugin-stronghold/4684fed1f5e7eb01885e40114accdcecb61962ed: - resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-stronghold/tar.gz/4684fed1f5e7eb01885e40114accdcecb61962ed} + github.com/tauri-apps/tauri-plugin-stronghold/d87b778f48ee12435efcf3f82d2e5efbb9541759: + resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-stronghold/tar.gz/d87b778f48ee12435efcf3f82d2e5efbb9541759} name: tauri-plugin-stronghold-api version: 0.0.0 dependencies: - '@tauri-apps/api': 1.4.0 + '@tauri-apps/api': 1.5.0 dev: false - github.com/tauri-apps/tauri-plugin-upload/40c0bc302a9dd8304762951e450ee84d53c2037b: - resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-upload/tar.gz/40c0bc302a9dd8304762951e450ee84d53c2037b} + github.com/tauri-apps/tauri-plugin-upload/5348082f7436b01f0b5c08d6ddfc4f760abbac7e: + resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-upload/tar.gz/5348082f7436b01f0b5c08d6ddfc4f760abbac7e} name: tauri-plugin-upload-api version: 0.0.0 dependencies: - '@tauri-apps/api': 1.4.0 + '@tauri-apps/api': 1.5.0 dev: false diff --git a/src/app.tsx b/src/app.tsx index d3197cb7..b99127cf 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,11 +1,12 @@ import { message } from '@tauri-apps/api/dialog'; -import { RouterProvider, createBrowserRouter, redirect } from 'react-router-dom'; +import { fetch } from '@tauri-apps/api/http'; +import '@vidstack/react/player/styles/default/theme.css'; +import { RouterProvider, createBrowserRouter, defer, redirect } from 'react-router-dom'; import 'reactflow/dist/style.css'; import { AuthCreateScreen } from '@app/auth/create'; import { AuthImportScreen } from '@app/auth/import'; import { OnboardingScreen } from '@app/auth/onboarding'; -import { BrowseScreen } from '@app/browse'; import { ErrorScreen } from '@app/error'; import { useStorage } from '@libs/storage/provider'; @@ -50,6 +51,17 @@ export default function App() { } }; + const relayLoader = async ({ params }) => { + return defer({ + relay: fetch(`https://${params.url}`, { + method: 'GET', + headers: { + Accept: 'application/nostr+json', + }, + }).then((res) => res.data), + }); + }; + const router = createBrowserRouter([ { path: '/', @@ -64,27 +76,6 @@ export default function App() { return { Component: SpaceScreen }; }, }, - { - path: 'browse', - element: , - errorElement: , - children: [ - { - path: '', - async lazy() { - const { BrowseUsersScreen } = await import('@app/browse/users'); - return { Component: BrowseUsersScreen }; - }, - }, - { - path: 'relays', - async lazy() { - const { BrowseRelaysScreen } = await import('@app/browse/relays'); - return { Component: BrowseRelaysScreen }; - }, - }, - ], - }, { path: 'users/:pubkey', async lazy() { @@ -113,6 +104,30 @@ export default function App() { return { Component: NWCScreen }; }, }, + { + path: 'explore', + async lazy() { + const { ExploreScreen } = await import('@app/explore'); + return { Component: ExploreScreen }; + }, + }, + { + path: 'relays', + async lazy() { + const { RelaysScreen } = await import('@app/relays'); + return { Component: RelaysScreen }; + }, + children: [ + { + path: ':url', + loader: relayLoader, + async lazy() { + const { RelayScreen } = await import('@app/relays/relay'); + return { Component: RelayScreen }; + }, + }, + ], + }, ], }, { diff --git a/src/app/browse/index.tsx b/src/app/browse/index.tsx deleted file mode 100644 index cb538e5e..00000000 --- a/src/app/browse/index.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { NavLink, Outlet } from 'react-router-dom'; -import { ReactFlowProvider } from 'reactflow'; -import { twMerge } from 'tailwind-merge'; - -export function BrowseScreen() { - return ( - -
-
-
-
- - twMerge( - 'inline-flex h-7 w-20 items-center justify-center rounded-full text-sm font-semibold', - isActive ? 'bg-white/10 hover:bg-white/20' : ' hover:bg-white/5' - ) - } - > - Users - - - twMerge( - 'inline-flex h-7 w-20 items-center justify-center rounded-full text-sm font-semibold', - isActive ? 'bg-white/10 hover:bg-white/20' : ' hover:bg-white/5' - ) - } - > - Relays - -
-
-
-
- -
-
- - ); -} diff --git a/src/app/browse/relays.tsx b/src/app/browse/relays.tsx deleted file mode 100644 index 6047990b..00000000 --- a/src/app/browse/relays.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export function BrowseRelaysScreen() { - return ( -
-
-

Content

-
-
-

Your relays

-
-
- ); -} diff --git a/src/app/browse/components/edge.tsx b/src/app/explore/components/edge.tsx similarity index 100% rename from src/app/browse/components/edge.tsx rename to src/app/explore/components/edge.tsx diff --git a/src/app/browse/components/groupTitle.tsx b/src/app/explore/components/groupTitle.tsx similarity index 100% rename from src/app/browse/components/groupTitle.tsx rename to src/app/explore/components/groupTitle.tsx diff --git a/src/app/browse/components/line.tsx b/src/app/explore/components/line.tsx similarity index 100% rename from src/app/browse/components/line.tsx rename to src/app/explore/components/line.tsx diff --git a/src/app/browse/components/userGroupNode.tsx b/src/app/explore/components/userGroupNode.tsx similarity index 92% rename from src/app/browse/components/userGroupNode.tsx rename to src/app/explore/components/userGroupNode.tsx index 7fe58277..0d06c297 100644 --- a/src/app/browse/components/userGroupNode.tsx +++ b/src/app/explore/components/userGroupNode.tsx @@ -1,6 +1,6 @@ import { Handle, Position } from 'reactflow'; -import { UserWithDrawer } from '@app/browse/components/userWithDrawer'; +import { UserWithDrawer } from '@app/explore/components/userWithDrawer'; import { GroupTitle } from './groupTitle'; diff --git a/src/app/browse/components/userLatestPosts.tsx b/src/app/explore/components/userLatestPosts.tsx similarity index 100% rename from src/app/browse/components/userLatestPosts.tsx rename to src/app/explore/components/userLatestPosts.tsx diff --git a/src/app/browse/components/userNode.tsx b/src/app/explore/components/userNode.tsx similarity index 100% rename from src/app/browse/components/userNode.tsx rename to src/app/explore/components/userNode.tsx diff --git a/src/app/browse/components/userWithDrawer.tsx b/src/app/explore/components/userWithDrawer.tsx similarity index 100% rename from src/app/browse/components/userWithDrawer.tsx rename to src/app/explore/components/userWithDrawer.tsx diff --git a/src/app/browse/users.tsx b/src/app/explore/index.tsx similarity index 71% rename from src/app/browse/users.tsx rename to src/app/explore/index.tsx index c638c546..fac38ae2 100644 --- a/src/app/browse/users.tsx +++ b/src/app/explore/index.tsx @@ -2,16 +2,17 @@ import { useCallback, useMemo, useRef } from 'react'; import ReactFlow, { Background, ConnectionMode, + ReactFlowProvider, addEdge, useEdgesState, useNodesState, useReactFlow, } from 'reactflow'; -import { Edge } from '@app/browse//components/edge'; -import { UserGroupNode } from '@app/browse//components/userGroupNode'; -import { Line } from '@app/browse/components/line'; -import { UserNode } from '@app/browse/components/userNode'; +import { Edge } from '@app/explore/components/edge'; +import { Line } from '@app/explore/components/line'; +import { UserGroupNode } from '@app/explore/components/userGroupNode'; +import { UserNode } from '@app/explore/components/userNode'; import { useStorage } from '@libs/storage/provider'; @@ -23,7 +24,7 @@ const getId = () => `${id++}`; const nodeTypes = { user: UserNode, userGroup: UserGroupNode }; const edgeTypes = { buttonedge: Edge }; -export function BrowseUsersScreen() { +export function ExploreScreen() { const { db } = useStorage(); const { getContactsByPubkey } = useNostr(); const { project } = useReactFlow(); @@ -91,26 +92,28 @@ export function BrowseUsersScreen() { ); return ( -
- - - -
+ +
+ + + +
+
); } diff --git a/src/app/relays/components/relayList.tsx b/src/app/relays/components/relayList.tsx new file mode 100644 index 00000000..08084521 --- /dev/null +++ b/src/app/relays/components/relayList.tsx @@ -0,0 +1,89 @@ +import { useQuery } from '@tanstack/react-query'; +import { useNavigate } from 'react-router-dom'; +import { VList } from 'virtua'; + +import { LoaderIcon, PlusIcon, ShareIcon } from '@shared/icons'; +import { User } from '@shared/user'; + +import { useNostr } from '@utils/hooks/useNostr'; + +export function RelayList() { + const navigate = useNavigate(); + + const { getAllRelaysByUsers } = useNostr(); + const { status, data } = useQuery( + ['relays'], + async () => { + return await getAllRelaysByUsers(); + }, + { refetchOnMount: false } + ); + + const openRelay = (relayUrl: string) => { + const url = new URL(relayUrl); + navigate(`/relays/${url.hostname}`); + }; + + return ( +
+ {status === 'loading' ? ( +
+
+ +

Loading relay...

+
+
+ ) : ( + +
+

+ All relays used by your follows +

+
+ {[...data].map(([key, value]) => ( +
+
+
+ + +
+
+ Relay: + + {key} + +
+
+
+ {value.slice(0, 4).map((item) => ( + + ))} + {value.length > 4 ? ( +
+ +{value.length} +
+ ) : null} +
+
+ ))} +
+ + )} +
+ ); +} diff --git a/src/app/relays/components/userRelay.tsx b/src/app/relays/components/userRelay.tsx new file mode 100644 index 00000000..95b3cd4b --- /dev/null +++ b/src/app/relays/components/userRelay.tsx @@ -0,0 +1,46 @@ +import { useQuery } from '@tanstack/react-query'; + +import { useNDK } from '@libs/ndk/provider'; +import { useStorage } from '@libs/storage/provider'; + +export function UserRelay() { + const { relayUrls } = useNDK(); + const { db } = useStorage(); + const { status, data } = useQuery( + ['user-relay'], + async () => { + return await db.getExplicitRelayUrls(); + }, + { refetchOnWindowFocus: false } + ); + + return ( +
+ {status === 'loading' ? ( +

Loading...

+ ) : ( +
+ {data.map((item) => ( +
+ {relayUrls.includes(item) ? ( + + + + + ) : ( + + + + + )} +

{item}

+
+ ))} +
+ )} +
+ ); +} diff --git a/src/app/relays/index.tsx b/src/app/relays/index.tsx new file mode 100644 index 00000000..41cfe7da --- /dev/null +++ b/src/app/relays/index.tsx @@ -0,0 +1,16 @@ +import { RelayList } from '@app/relays/components/relayList'; +import { UserRelay } from '@app/relays/components/userRelay'; + +export function RelaysScreen() { + return ( +
+ +
+
+

Connected relays

+
+ +
+
+ ); +} diff --git a/src/app/relays/relay.tsx b/src/app/relays/relay.tsx new file mode 100644 index 00000000..210423b3 --- /dev/null +++ b/src/app/relays/relay.tsx @@ -0,0 +1,19 @@ +import { Suspense } from 'react'; +import { Await, useLoaderData } from 'react-router-dom'; + +export function RelayScreen() { + const data: { relay?: { [key: string]: string } } = useLoaderData(); + + return ( +
+ Loading...

}> + Could not load relay information 😬
} + > + {(resolvedRelay) =>

{JSON.stringify(resolvedRelay)}

} + + +
+ ); +} diff --git a/src/app/space/components/toggle.tsx b/src/app/space/components/toggle.tsx index 07e32c49..1b4eebc3 100644 --- a/src/app/space/components/toggle.tsx +++ b/src/app/space/components/toggle.tsx @@ -1,6 +1,6 @@ import { useStorage } from '@libs/storage/provider'; -import { PlusIcon } from '@shared/icons'; +import { HandArrowDownIcon, PlusIcon } from '@shared/icons'; import { WidgetKinds, useWidgets } from '@stores/widgets'; @@ -9,17 +9,22 @@ export function ToggleWidgetList() { const setWidget = useWidgets((state) => state.setWidget); return ( -
- +
+
+
+ +
+ +
); } diff --git a/src/shared/icons/handArrowDown.tsx b/src/shared/icons/handArrowDown.tsx new file mode 100644 index 00000000..3eeeb8de --- /dev/null +++ b/src/shared/icons/handArrowDown.tsx @@ -0,0 +1,29 @@ +import { SVGProps } from 'react'; + +export function HandArrowDownIcon( + props: JSX.IntrinsicAttributes & SVGProps +) { + return ( + + + + + ); +} diff --git a/src/shared/icons/index.ts b/src/shared/icons/index.ts index 24e62684..eb6bf2ca 100644 --- a/src/shared/icons/index.ts +++ b/src/shared/icons/index.ts @@ -66,3 +66,4 @@ export * from './stars'; export * from './nwc'; export * from './timeline'; export * from './dots'; +export * from './handArrowDown'; diff --git a/src/shared/navigation.tsx b/src/shared/navigation.tsx index d3b2530a..14fe54cf 100644 --- a/src/shared/navigation.tsx +++ b/src/shared/navigation.tsx @@ -90,7 +90,7 @@ export function Navigation() { Home twMerge( @@ -104,7 +104,24 @@ export function Navigation() { - Browse + Relays + + + twMerge( + 'flex h-10 items-center gap-2.5 rounded-r-lg border-l-2 pl-4 pr-3', + isActive + ? 'border-fuchsia-500 bg-white/5 text-white' + : 'border-transparent text-white/70' + ) + } + > + + + + Explore - + src={url} + poster={`https://thumbnail.video/api/get?url=${url}&seconds=1`} + load="visible" + aspectRatio="16/9" + crossorigin="" + > + +
); } diff --git a/src/shared/notes/preview/image.tsx b/src/shared/notes/preview/image.tsx index 3d2964e6..31c1be25 100644 --- a/src/shared/notes/preview/image.tsx +++ b/src/shared/notes/preview/image.tsx @@ -2,7 +2,6 @@ import { downloadDir } from '@tauri-apps/api/path'; import { download } from 'tauri-plugin-upload-api'; import { DownloadIcon } from '@shared/icons'; -import { Image } from '@shared/image'; export function ImagePreview({ urls, truncate }: { urls: string[]; truncate?: boolean }) { const downloadImage = async (url: string) => { @@ -16,12 +15,15 @@ export function ImagePreview({ urls, truncate }: { urls: string[]; truncate?: bo
{urls.map((url) => (
- {url}
); diff --git a/src/shared/user.tsx b/src/shared/user.tsx index 13c1a519..7c467bd9 100644 --- a/src/shared/user.tsx +++ b/src/shared/user.tsx @@ -29,7 +29,8 @@ export const User = memo(function User({ | 'chat' | 'large' | 'thread' - | 'avatar'; + | 'avatar' + | 'stacked'; embedProfile?: string; }) { const { status, user } = useProfile(pubkey, embedProfile); @@ -186,6 +187,28 @@ export const User = memo(function User({ ); } + if (variant === 'stacked') { + return ( + + + + {pubkey} + + + ); + } + if (variant === 'repost') { return (
diff --git a/src/shared/widgets/eventLoader.tsx b/src/shared/widgets/eventLoader.tsx index 72492253..0f15b7aa 100644 --- a/src/shared/widgets/eventLoader.tsx +++ b/src/shared/widgets/eventLoader.tsx @@ -19,7 +19,7 @@ export function EventLoader({ firstTime }: { firstTime: boolean }) { useEffect(() => { async function getEvents() { const events = await getAllEventsSinceLastLogin(); - console.log('total event found: ', events.data.length); + console.log('total new events has found: ', events.data.length); const promises = await Promise.all( events.data.map(async (event) => await db.createEvent(event)) diff --git a/src/utils/hooks/useNostr.ts b/src/utils/hooks/useNostr.ts index dbd4e82c..9aae02ac 100644 --- a/src/utils/hooks/useNostr.ts +++ b/src/utils/hooks/useNostr.ts @@ -305,6 +305,31 @@ export function useNostr() { return events as unknown as NDKEvent[]; }; + const getAllRelaysByUsers = async () => { + const relayMap = new Map(); + const relayEvents = fetcher.fetchLatestEventsPerAuthor( + { + authors: db.account.follows, + relayUrls: relayUrls, + }, + { kinds: [NDKKind.RelayList] }, + 5 + ); + + for await (const { author, events } of relayEvents) { + if (events[0]) { + events[0].tags.forEach((tag) => { + const users = relayMap.get(tag[1]); + + if (!users) return relayMap.set(tag[1], [author]); + return users.push(author); + }); + } + } + + return relayMap; + }; + const publish = async ({ content, kind, @@ -450,5 +475,6 @@ export function useNostr() { upload, getContactsByPubkey, getEventsByPubkey, + getAllRelaysByUsers, }; }