Skip to content

Commit

Permalink
feat: new nostr hooks (keep-starknet-strange#132)
Browse files Browse the repository at this point in the history
* new nostr hooks

* new hooks

* fix type error

* Fix conflicts

* fix query keys for hooks
  • Loading branch information
ugur-eren authored May 29, 2024
1 parent 7bd97c4 commit 33d0344
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 9 deletions.
5 changes: 5 additions & 0 deletions JoyboyCommunity/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export {useProfile} from './useProfile';
export {useReactions} from './useReactions';
export {useReplyNotes} from './useReplyNotes';
export {useReposts} from './useReposts';
export {useRootNotes} from './useRootNotes';
34 changes: 34 additions & 0 deletions JoyboyCommunity/src/hooks/useProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {useQuery} from '@tanstack/react-query';

import {useNostrContext} from '../context/NostrContext';
import {EventKind} from '../types';

export type UseProfileOptions = {
publicKey: string;
};

export const useProfile = (options: UseProfileOptions) => {
const {pool, othersRelays} = useNostrContext();

return useQuery({
queryKey: ['profile', options.publicKey],
queryFn: async () => {
const profileEvent = await pool.get(othersRelays, {
kinds: [EventKind.Metadata],
authors: [options?.publicKey],
});

const profile = JSON.parse(profileEvent.content) as Record<string, string | undefined>;

return {
username: profile.name,
displayName: profile.display_name ?? profile.displayName,
website: profile.website,
banner: profile.banner,
about: profile.about,
picture: profile.picture,
};
},
placeholderData: {} as any,
});
};
38 changes: 38 additions & 0 deletions JoyboyCommunity/src/hooks/useReactions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {useInfiniteQuery} from '@tanstack/react-query';

import {useNostrContext} from '../context/NostrContext';
import {EventKind} from '../types';

export type UseReactionsOptions = {
authors?: string[];
search?: string;
};

export const useReactions = (options?: UseReactionsOptions) => {
const {pool, othersRelays} = useNostrContext();

return useInfiniteQuery({
initialPageParam: Math.round(Date.now() / 1000),
queryKey: ['reactions', options?.authors, options?.search],
getNextPageParam: (lastPage: any, allPages, lastPageParam) => {
if (!lastPage?.length) return undefined;

const pageParam = lastPage[lastPage.length - 1].created_at;

if (!pageParam || pageParam === lastPageParam) return undefined;
return pageParam;
},
queryFn: async ({pageParam}) => {
const notes = await pool.querySync(othersRelays, {
kinds: [EventKind.Reaction],
authors: options?.authors,
search: options?.search,
until: pageParam,
limit: 20,
});

return notes;
},
placeholderData: {pages: [], pageParams: []},
});
};
41 changes: 41 additions & 0 deletions JoyboyCommunity/src/hooks/useReplyNotes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {useInfiniteQuery} from '@tanstack/react-query';

import {useNostrContext} from '../context/NostrContext';
import {EventKind} from '../types';

export type UseReplyNotesOptions = {
noteId?: string;
authors?: string[];
search?: string;
};

export const useReplyNotes = (options?: UseReplyNotesOptions) => {
const {pool, othersRelays} = useNostrContext();

return useInfiniteQuery({
initialPageParam: Math.round(Date.now() / 1000),
queryKey: ['replyNotes', options?.noteId, options?.authors, options?.search],
getNextPageParam: (lastPage: any, allPages, lastPageParam) => {
if (!lastPage?.length) return undefined;

const pageParam = lastPage[lastPage.length - 1].created_at;

if (!pageParam || pageParam === lastPageParam) return undefined;
return pageParam;
},
queryFn: async ({pageParam}) => {
const notes = await pool.querySync(othersRelays, {
kinds: [EventKind.Note],
authors: options?.authors,
search: options?.search,
until: pageParam,
limit: 20,

'#e': options?.noteId ? [options.noteId] : undefined,
});

return notes.filter((note) => note.tags.every((tag) => tag[0] === 'e'));
},
placeholderData: {pages: [], pageParams: []},
});
};
38 changes: 38 additions & 0 deletions JoyboyCommunity/src/hooks/useReposts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {useInfiniteQuery} from '@tanstack/react-query';

import {useNostrContext} from '../context/NostrContext';
import {EventKind} from '../types';

export type UseRepostsOptions = {
authors?: string[];
search?: string;
};

export const useReposts = (options?: UseRepostsOptions) => {
const {pool, othersRelays} = useNostrContext();

return useInfiniteQuery({
initialPageParam: Math.round(Date.now() / 1000),
queryKey: ['reposts', options?.authors, options?.search],
getNextPageParam: (lastPage: any, allPages, lastPageParam) => {
if (!lastPage?.length) return undefined;

const pageParam = lastPage[lastPage.length - 1].created_at;

if (!pageParam || pageParam === lastPageParam) return undefined;
return pageParam;
},
queryFn: async ({pageParam}) => {
const reposts = await pool.querySync(othersRelays, {
kinds: [EventKind.Repost],
authors: options?.authors,
search: options?.search,
until: pageParam,
limit: 20,
});

return reposts;
},
placeholderData: {pages: [], pageParams: []},
});
};
38 changes: 38 additions & 0 deletions JoyboyCommunity/src/hooks/useRootNotes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {useInfiniteQuery} from '@tanstack/react-query';

import {useNostrContext} from '../context/NostrContext';
import {EventKind} from '../types';

export type UseRootNotesOptions = {
authors?: string[];
search?: string;
};

export const useRootNotes = (options?: UseRootNotesOptions) => {
const {pool, othersRelays} = useNostrContext();

return useInfiniteQuery({
initialPageParam: Math.round(Date.now() / 1000),
queryKey: ['rootNotes', options?.authors, options?.search],
getNextPageParam: (lastPage: any, allPages, lastPageParam) => {
if (!lastPage?.length) return undefined;

const pageParam = lastPage[lastPage.length - 1].created_at;

if (!pageParam || pageParam === lastPageParam) return undefined;
return pageParam;
},
queryFn: async ({pageParam}) => {
const notes = await pool.querySync(othersRelays, {
kinds: [EventKind.Note],
authors: options?.authors,
search: options?.search,
until: pageParam,
limit: 20,
});

return notes.filter((note) => note.tags.every((tag) => tag[0] !== 'e'));
},
placeholderData: {pages: [], pageParams: []},
});
};
15 changes: 6 additions & 9 deletions JoyboyCommunity/src/modules/feed/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {FlatList, RefreshControl} from 'react-native-gesture-handler';
import {SafeAreaView} from 'react-native-safe-area-context';
import styled from 'styled-components/native';

import {useGetPoolEventsNotes} from '../../hooks/useNostr';
import {useRootNotes} from '../../hooks';
import {Post} from '../../shared/components/Post';
import FloatingPostButton from './FloatingPostButton';
import {styles} from './style';
Expand All @@ -19,11 +19,7 @@ const FixedPostButton = styled(View)`
export default function Feed() {
const bottomBarHeight = useBottomTabBarHeight();

const {
data: poolEventNotesData,
isLoading: poolEventNotesDataLoading,
refetch,
} = useGetPoolEventsNotes();
const notes = useRootNotes();

const stories = [
{name: 'Luffy', img: require('../../assets/feed/images/story-1.png')},
Expand Down Expand Up @@ -73,14 +69,14 @@ export default function Feed() {
/>
</View>

{poolEventNotesDataLoading && <ActivityIndicator />}
{notes.isLoading && <ActivityIndicator />}

<FlatList
contentContainerStyle={{
paddingTop: 16,
paddingBottom: bottomBarHeight,
}}
data={poolEventNotesData}
data={notes.data.pages.flat()}
keyExtractor={(item) => item?.id}
renderItem={({item}) => {
return (
Expand All @@ -91,10 +87,11 @@ export default function Feed() {
);
}}
refreshControl={
<RefreshControl refreshing={poolEventNotesDataLoading} onRefresh={() => refetch()} />
<RefreshControl refreshing={notes.isFetching} onRefresh={() => notes.refetch()} />
}
/>
</ImageBackground>

<FixedPostButton>
<FloatingPostButton />
</FixedPostButton>
Expand Down
1 change: 1 addition & 0 deletions JoyboyCommunity/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Event as EventNostr, Filter, SimplePool} from 'nostr-tools';

export * from './nostr';
export * from './post';
export * from './routes';

Expand Down
17 changes: 17 additions & 0 deletions JoyboyCommunity/src/types/nostr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export enum EventKind {
Metadata = 0,
Note = 1,
Follow = 3,
EncryptedDM = 4,
EventDeletion = 5,
Repost = 6,
Reaction = 7,
BadgeAward = 8,
GroupChatMessage = 9,
GroupChatThreadedReply = 10,
GroupThread = 11,
GroupThreadReply = 12,
Seal = 13,
DirectMessage = 14,
GenericRepost = 16,
}

0 comments on commit 33d0344

Please sign in to comment.