Skip to content

Commit

Permalink
fix bookmarks hook (#90)
Browse files Browse the repository at this point in the history
* fix bookmarks hook

* add bookmarks to profile

* update bookmarks source data

* add remove bookmark, mark as bookmarked
  • Loading branch information
lindsaymoralesb authored Aug 31, 2024
1 parent 9786312 commit 9f878f6
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 90 deletions.
17 changes: 13 additions & 4 deletions apps/mobile/src/assets/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -414,17 +414,26 @@ export const LikeIcon: React.FC<SvgProps> = (props) => {
};

export const BookmarkIcon: React.FC<SvgProps> = (props) => (
<Svg width="32" height="32" viewBox="0 0 21 21" {...props}>
<Path
fill="none"
stroke="currentColor"
stroke-width="2"
d="M4 2C2.343 2 1 3.343 1 5v15l7-4 7 4V5c0-1.657-1.343-3-3-3H4z"
/>
</Svg>
);

export const BookmarkFillIcon: React.FC<SvgProps> = (props) => (
<Svg width="32" height="32" viewBox="0 0 21 21" {...props}>
<Path
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
d="M 6.0097656 2 C 4.9143111 2 4.0097656 2.9025988 4.0097656 3.9980469 L 4 22 L 12 19 L 20 22 L 20 20.556641 L 20 4 C 20 2.9069372 19.093063 2 18 2 L 6.0097656 2 z M 6.0097656 4 L 18 4 L 18 19.113281 L 12 16.863281 L 6.0019531 19.113281 L 6.0097656 4 z"
// d="M 12.8125 2 C 12.335938 2.089844 11.992188 2.511719 12 3 L 12 47 C 11.996094 47.359375 12.1875 47.691406 12.496094 47.871094 C 12.804688 48.054688 13.1875 48.054688 13.5 47.875 L 25 41.15625 L 36.5 47.875 C 36.8125 48.054688 37.195313 48.054688 37.503906 47.871094 C 37.8125 47.691406 38.003906 47.359375 38 47 L 38 3 C 38 2.449219 37.550781 2 37 2 L 13 2 C 12.96875 2 12.9375 2 12.90625 2 C 12.875 2 12.84375 2 12.8125 2 Z M 14 4 L 36 4 L 36 45.25 L 25.5 39.125 C 25.191406 38.945313 24.808594 38.945313 24.5 39.125 L 14 45.25 Z"
d="M4 2C2.343 2 1 3.343 1 5v15l7-4 7 4V5c0-1.657-1.343-3-3-3H4z"
/>
</Svg>
);


export const LikeFillIcon: React.FC<SvgProps> = (props) => {
return (
<Svg width="26" height="26" viewBox="0 0 20 20" fill="none" {...props}>
Expand Down
25 changes: 17 additions & 8 deletions apps/mobile/src/modules/Post/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {useQueryClient} from '@tanstack/react-query';
import {useProfile, useReact, useReactions, useReplyNotes, useRepost, useBookmark} from 'afk_nostr_sdk';
// import { useAuth } from '../../store/auth';
import {useAuth} from 'afk_nostr_sdk';
import {useMemo, useState} from 'react';
import {useEffect, useMemo, useState} from 'react';
import {ActivityIndicator, Image, Pressable, View} from 'react-native';
import Animated, {
Easing,
Expand All @@ -28,10 +28,11 @@ export type PostProps = {
asComment?: boolean;
event?: NDKEvent;
repostedEventProps?:string;
isRepost?:boolean
isRepost?:boolean;
isBookmarked?:boolean;
};

export const Post: React.FC<PostProps> = ({asComment, event, repostedEventProps, isRepost}) => {
export const Post: React.FC<PostProps> = ({asComment, event, repostedEventProps, isRepost, isBookmarked = false}) => {
const repostedEvent = repostedEventProps ?? undefined;

const {theme} = useTheme();
Expand All @@ -50,7 +51,7 @@ export const Post: React.FC<PostProps> = ({asComment, event, repostedEventProps,
const react = useReact();
const queryClient = useQueryClient();
const repostMutation = useRepost({ event });
const { bookmarkNote } = useBookmark(publicKey);
const { bookmarkNote, removeBookmark } = useBookmark(publicKey);

const [menuOpen, setMenuOpen] = useState(false);

Expand Down Expand Up @@ -137,11 +138,16 @@ export const Post: React.FC<PostProps> = ({asComment, event, repostedEventProps,
const handleBookmark = async () => {
if (!event) return;
try {
await bookmarkNote({ event });
showToast({title: 'Post bookmarked successfully', type: 'success'});
if (isBookmarked) {
await removeBookmark({ eventId: event.id });
showToast({ title: 'Post removed from bookmarks', type: 'success' });
} else {
await bookmarkNote({ event });
showToast({ title: 'Post bookmarked successfully', type: 'success' });
}
} catch (error) {
console.error('Bookmark error:', error);
showToast({title: 'Failed to bookmark', type: 'error'});
showToast({ title: 'Failed to bookmark', type: 'error' });
}
};

Expand Down Expand Up @@ -296,7 +302,10 @@ export const Post: React.FC<PostProps> = ({asComment, event, repostedEventProps,
style={{marginHorizontal: 3}}
onPress={handleBookmark}
>
<Icon name="BookmarkIcon" size={20} title="Bookmark" />
<Icon
name={isBookmarked ? "BookmarkFillIcon" : "BookmarkIcon"}
size={20}
title={isBookmarked ? "Bookmarked" : "Bookmark"} />
</Pressable>
</View>

Expand Down
5 changes: 3 additions & 2 deletions apps/mobile/src/modules/PostCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { useState } from 'react';
export type PostCardProps = {
event?: NDKEvent;
isRepostProps?:boolean;
isBookmarked?:boolean;
};

export const PostCard: React.FC<PostCardProps> = ({ event, isRepostProps }) => {
export const PostCard: React.FC<PostCardProps> = ({ event, isRepostProps, isBookmarked }) => {
const styles = useStyles(stylesheet);

let repostedEvent = undefined;
Expand All @@ -21,7 +22,7 @@ export const PostCard: React.FC<PostCardProps> = ({ event, isRepostProps }) => {
}
return (
<View style={styles.container}>
<Post event={event} repostedEventProps={repostedEvent} isRepost={isRepost}/>
<Post event={event} repostedEventProps={repostedEvent} isRepost={isRepost} isBookmarked={isBookmarked} />
</View>
);
};
75 changes: 47 additions & 28 deletions apps/mobile/src/screens/Profile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useReposts, useRootNotes, useSearch, useSearchNotes } from 'afk_nostr_sdk';
import { useBookmark, useReposts, useRootNotes, useSearch } from 'afk_nostr_sdk';
import { ActivityIndicator, FlatList, Pressable, RefreshControl, ScrollView, View } from 'react-native';

import { useStyles } from '../../hooks';
Expand All @@ -8,20 +8,41 @@ import { ProfileInfo } from './Info';
import stylesheet from './styles';
import { useMemo, useState } from 'react';
import { NDKKind } from '@nostr-dev-kit/ndk';
import { Button, Text } from '../../components';
import { Text } from '../../components';

export const Profile: React.FC<ProfileScreenProps> = ({ route }) => {
const { publicKey } = route.params ?? {};
const styles = useStyles(stylesheet);
const [ndkKind, setNdkKind] = useState<NDKKind>(NDKKind.Text)
const [ndkKinds, setNdkKind] = useState<NDKKind[]>([NDKKind.Text]);

const kindFilter = useMemo(() => {
return ndkKind
}, [ndkKind])
return ndkKinds
}, [ndkKinds])

const notesSearch = useRootNotes({ authors: [publicKey] });
const search = useSearch({ authors: [publicKey], kind: kindFilter });
const search = useSearch({ authors: [publicKey], kinds: kindFilter });
const reposts = useReposts({ authors: [publicKey] });
const { bookmarksWithNotes } = useBookmark(publicKey);

// Extract all bookmarked note IDs
const bookmarkedNoteIds = useMemo(() => {
if (!bookmarksWithNotes) return new Set<string>();

const ids = new Set<string>();
bookmarksWithNotes.forEach(bookmark => {
bookmark.notes.forEach(note => {
ids.add(note?.id || '');
});
});
return ids;
}, [bookmarksWithNotes]);

// Function to check if a note is bookmarked
const isBookmarked = (noteId: string) => bookmarkedNoteIds.has(noteId);

const getData = ndkKinds.includes(NDKKind.BookmarkList) || ndkKinds.includes(NDKKind.BookmarkSet)
? bookmarksWithNotes?.map(bookmark => bookmark.notes).flat() || []
: search.data?.pages.flat();

return (
<View style={styles.container}>
Expand All @@ -33,40 +54,38 @@ export const Profile: React.FC<ProfileScreenProps> = ({ route }) => {
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
paddingVertical: 5,
paddingHorizontal:5,
flexDirection: 'row',
rowGap: 3,
gap: 3,
columnGap: 3
}}
style={{
paddingHorizontal:5,
paddingVertical: 5,
flexDirection: 'row',
rowGap: 3,
gap: 3,
columnGap: 3
}}
contentContainerStyle={styles.optionsContentContainer}
style={styles.optionsContainer}
>
<Pressable onPress={() => setNdkKind(NDKKind.Text)}>
<Pressable
onPress={() => setNdkKind([NDKKind.Text])}
style={[styles.option, ndkKinds.includes(NDKKind.Text) && styles.selected]}
>
<Text>Notes</Text>
</Pressable>
<Pressable onPress={() => setNdkKind(NDKKind.Repost)}>
<Pressable
onPress={() => setNdkKind([NDKKind.Repost])}
style={[styles.option, ndkKinds.includes(NDKKind.Repost) && styles.selected]}
>
<Text>Repost</Text>
</Pressable>
<Pressable
onPress={() => setNdkKind([NDKKind.BookmarkList, NDKKind.BookmarkSet])}
style={[styles.option, ndkKinds.includes(NDKKind.BookmarkList) && styles.selected]}
>
<Text>Bookmarks</Text>
</Pressable>
</ScrollView>
</>
}
data={search.data?.pages.flat()}
data={getData}
keyExtractor={(item) => item.id}
renderItem={({ item }) => {
if (ndkKind == NDKKind.Repost) {
const itemReposted = JSON.parse(item?.content)
if (ndkKinds.includes(NDKKind.Repost)) {
const itemReposted = JSON.parse(item?.content);
return <PostCard key={item?.id} event={itemReposted} isRepostProps={true} />
}
return <PostCard key={item?.id} event={item} />
return <PostCard key={item?.id} event={item} isBookmarked={isBookmarked(item.id)} />
}}
refreshControl={
<RefreshControl refreshing={search.isFetching} onRefresh={() => search.refetch()} />
Expand Down
29 changes: 29 additions & 0 deletions apps/mobile/src/screens/Profile/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,33 @@ export default ThemedStyleSheet((theme) => ({
flex: 1,
backgroundColor: theme.colors.background,
},
optionsContentContainer: {
paddingVertical: 5,
paddingHorizontal:5,
flexDirection: 'row',
rowGap: 3,
gap: 3,
columnGap: 15,
},
optionsContainer: {
paddingHorizontal:5,
paddingVertical: 5,
flexDirection: 'row',
rowGap: 3,
gap: 3,
columnGap: 3
},
option: {
paddingVertical: 10,
paddingHorizontal: 20,
borderWidth: 1,
borderStyle: 'solid',
borderColor: theme.colors.primary,
borderRadius: 20,
color: theme.colors.textLight,
},
selected: {
backgroundColor: theme.colors.primary,
color: theme.colors.text
}
}));
Loading

0 comments on commit 9f878f6

Please sign in to comment.