This commit is contained in:
Ren Amamiya
2023-09-21 15:28:01 +07:00
parent 17fe3bb1f6
commit 413571ee7f
11 changed files with 235 additions and 207 deletions

View File

@@ -60,10 +60,10 @@ const router = createBrowserRouter([
},
},
{
path: 'timeline',
path: 'browse',
async lazy() {
const { TimelineScreen } = await import('@app/timeline');
return { Component: TimelineScreen };
const { BrowseScreen } = await import('@app/browse');
return { Component: BrowseScreen };
},
},
{

View File

@@ -1,4 +1,4 @@
export function TimelineScreen() {
export function BrowseScreen() {
return (
<div>
<p>TODO</p>

View File

@@ -1,18 +1,25 @@
// inspire by: https://github.com/nostr-dev-kit/ndk-react/
import NDK from '@nostr-dev-kit/ndk';
import { ndkAdapter } from '@nostr-fetch/adapter-ndk';
import { message } from '@tauri-apps/api/dialog';
import { fetch } from '@tauri-apps/api/http';
import { NostrFetcher } from 'nostr-fetch';
import { useEffect, useMemo, useState } from 'react';
import TauriAdapter from '@libs/ndk/cache';
import { useStorage } from '@libs/storage/provider';
export const NDKInstance = () => {
const { db } = useStorage();
const [ndk, setNDK] = useState<NDK | undefined>(undefined);
const [relayUrls, setRelayUrls] = useState<string[]>([]);
const { db } = useStorage();
const cacheAdapter = useMemo(() => new TauriAdapter(), [ndk]);
const fetcher = useMemo(
() => (ndk ? NostrFetcher.withCustomPool(ndkAdapter(ndk)) : null),
[ndk]
);
// TODO: fully support NIP-11
async function getExplicitRelays() {
@@ -81,5 +88,6 @@ export const NDKInstance = () => {
return {
ndk,
relayUrls,
fetcher,
};
};

View File

@@ -1,5 +1,6 @@
// source: https://github.com/nostr-dev-kit/ndk-react/
import NDK from '@nostr-dev-kit/ndk';
import { NostrFetcher } from 'nostr-fetch';
import { PropsWithChildren, createContext, useContext } from 'react';
import { NDKInstance } from '@libs/ndk/instance';
@@ -7,21 +8,24 @@ import { NDKInstance } from '@libs/ndk/instance';
interface NDKContext {
ndk: undefined | NDK;
relayUrls: string[];
fetcher: NostrFetcher;
}
const NDKContext = createContext<NDKContext>({
ndk: undefined,
relayUrls: [],
fetcher: undefined,
});
const NDKProvider = ({ children }: PropsWithChildren<object>) => {
const { ndk, relayUrls } = NDKInstance();
const { ndk, relayUrls, fetcher } = NDKInstance();
return (
<NDKContext.Provider
value={{
ndk,
relayUrls,
fetcher,
}}
>
{children}

View File

@@ -7,13 +7,7 @@ import { ChatsList } from '@app/chats/components/list';
import { ActiveAccount } from '@shared/accounts/active';
import { ComposerModal } from '@shared/composer';
import { Frame } from '@shared/frame';
import {
BellIcon,
NavArrowDownIcon,
NwcIcon,
SpaceIcon,
TimeLineIcon,
} from '@shared/icons';
import { BellIcon, NavArrowDownIcon, NwcIcon, SpaceIcon, WorldIcon } from '@shared/icons';
import { useActivities } from '@stores/activities';
import { useSidebar } from '@stores/sidebar';
@@ -38,23 +32,6 @@ export function Navigation() {
className="scrollbar-hide flex h-full flex-1 flex-col gap-6 overflow-y-auto pb-32"
>
<div className="flex flex-col pr-3">
<NavLink
to="/timeline"
preventScrollReset={true}
className={({ isActive }) =>
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'
)
}
>
<span className="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded bg-white/10 backdrop-blur-xl">
<TimeLineIcon className="h-4 w-4 text-white" />
</span>
Timeline
</NavLink>
<NavLink
to="/"
preventScrollReset={true}
@@ -70,7 +47,24 @@ export function Navigation() {
<span className="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded bg-white/10 backdrop-blur-xl">
<SpaceIcon className="h-4 w-4 text-white" />
</span>
Space
Home
</NavLink>
<NavLink
to="/browse"
preventScrollReset={true}
className={({ isActive }) =>
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'
)
}
>
<span className="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded bg-white/10 backdrop-blur-xl">
<WorldIcon className="h-4 w-4 text-white" />
</span>
Browse
</NavLink>
<NavLink
to="/notifications"

View File

@@ -3,6 +3,7 @@ import { useQuery } from '@tanstack/react-query';
import { nip19 } from 'nostr-tools';
import { useCallback } from 'react';
import { Link } from 'react-router-dom';
import { twMerge } from 'tailwind-merge';
import { useNDK } from '@libs/ndk/provider';
@@ -17,7 +18,13 @@ import {
} from '@shared/notes';
import { User } from '@shared/user';
export function Repost({ event }: { event: NDKEvent }) {
export function Repost({
event,
lighter = false,
}: {
event: NDKEvent;
lighter?: boolean;
}) {
const embedEvent: null | NDKEvent =
event.content.length > 0 ? JSON.parse(event.content) : null;
@@ -55,7 +62,12 @@ export function Repost({ event }: { event: NDKEvent }) {
if (embedEvent) {
return (
<div className="h-min w-full px-3 pb-3">
<div className="relative flex flex-col gap-10 overflow-hidden rounded-xl bg-white/10 px-3 py-3 backdrop-blur-xl">
<div
className={twMerge(
'relative flex flex-col gap-10 overflow-hidden rounded-xl px-3 py-3',
!lighter ? 'bg-white/10 backdrop-blur-xl' : ''
)}
>
<User pubkey={event.pubkey} time={event.created_at} variant="repost" />
<div className="relative flex flex-col">
<User pubkey={embedEvent.pubkey} time={embedEvent.created_at} />
@@ -89,7 +101,12 @@ export function Repost({ event }: { event: NDKEvent }) {
return (
<div className="h-min w-full px-3 pb-3">
<div className="relative overflow-hidden rounded-xl bg-white/10 px-3 py-3 backdrop-blur-xl">
<div
className={twMerge(
'relative overflow-hidden rounded-xl px-3 py-3',
!lighter ? 'bg-white/10 backdrop-blur-xl' : ''
)}
>
<div className="relative flex flex-col">
<div className="relative z-10 flex items-start gap-3">
<div className="inline-flex h-11 w-11 items-end justify-center rounded-lg bg-black pb-1">
@@ -122,7 +139,12 @@ export function Repost({ event }: { event: NDKEvent }) {
return (
<div className="h-min w-full px-3 pb-3">
<div className="relative flex flex-col gap-10 overflow-hidden rounded-xl bg-white/10 px-3 py-3 backdrop-blur-xl">
<div
className={twMerge(
'relative flex flex-col gap-10 overflow-hidden rounded-xl px-3 py-3',
!lighter ? 'bg-white/10 backdrop-blur-xl' : ''
)}
>
<User pubkey={event.pubkey} time={event.created_at} variant="repost" />
<div className="relative flex flex-col">
<User pubkey={data.pubkey} time={data.created_at} />

View File

@@ -1,5 +1,6 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { ReactNode } from 'react';
import { twMerge } from 'tailwind-merge';
import { ChildNote, NoteActions } from '@shared/notes';
import { User } from '@shared/user';
@@ -9,16 +10,23 @@ export function NoteWrapper({
children,
root,
reply,
lighter = false,
}: {
event: NDKEvent;
children: ReactNode;
repost?: boolean;
root?: string;
reply?: string;
lighter?: boolean;
}) {
return (
<div className="h-min w-full px-3 pb-3">
<div className="relative overflow-hidden rounded-xl bg-white/10 px-3 py-3 backdrop-blur-xl">
<div
className={twMerge(
'relative overflow-hidden rounded-xl px-3 py-3',
!lighter ? 'bg-white/10 backdrop-blur-xl' : 'bg-transparent'
)}
>
<div className="relative">{root && <ChildNote id={root} />}</div>
<div className="relative">{reply && <ChildNote id={reply} root={root} />}</div>
<div className="relative flex flex-col">

View File

@@ -58,7 +58,7 @@ export function LocalNetworkWidget() {
case NDKKind.Text:
return (
<div
key={dbEvent.id + index}
key={dbEvent.id + dbEvent.root_id + dbEvent.reply_id + index}
data-index={index}
ref={virtualizer.measureElement}
>

View File

@@ -6,11 +6,9 @@ import {
NDKSubscription,
NDKUser,
} from '@nostr-dev-kit/ndk';
import { ndkAdapter } from '@nostr-fetch/adapter-ndk';
import { message, open } from '@tauri-apps/api/dialog';
import { Body, fetch } from '@tauri-apps/api/http';
import { LRUCache } from 'lru-cache';
import { NostrFetcher } from 'nostr-fetch';
import { nip19 } from 'nostr-tools';
import { useMemo } from 'react';
@@ -24,8 +22,8 @@ import { nHoursAgo } from '@utils/date';
import { NDKEventWithReplies, NostrBuildResponse } from '@utils/types';
export function useNostr() {
const { ndk, relayUrls } = useNDK();
const { db } = useStorage();
const { ndk, relayUrls, fetcher } = useNDK();
const privkey = useStronghold((state) => state.privkey);
const subManager = useMemo(
@@ -137,7 +135,6 @@ export function useNostr() {
const prefetchEvents = async () => {
try {
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk));
const dbEventsEmpty = await db.isEventsEmpty();
let since: number;
@@ -173,7 +170,6 @@ export function useNostr() {
const fetchActivities = async () => {
try {
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk));
const events = await fetcher.fetchAllEvents(
relayUrls,
{
@@ -197,7 +193,6 @@ export function useNostr() {
};
const fetchNIP04Chats = async () => {
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk));
const events = await fetcher.fetchAllEvents(
relayUrls,
{
@@ -215,8 +210,6 @@ export function useNostr() {
};
const fetchNIP04Messages = async (sender: string) => {
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk));
const senderMessages = await fetcher.fetchAllEvents(
relayUrls,
{
@@ -246,7 +239,6 @@ export function useNostr() {
const fetchAllReplies = async (id: string, data?: NDKEventWithReplies[]) => {
let events = data || null;
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk));
if (!data) {
events = (await fetcher.fetchAllEvents(