diff --git a/src/App.tsx b/src/App.tsx
index 50b7afc..7ad7c82 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -17,14 +17,14 @@ export default function App(): JSX.Element {
-
-
+
+
-
-
+
+
diff --git a/src/providers/FeedProvider.tsx b/src/providers/FeedProvider.tsx
index 5d13c0c..8e1b123 100644
--- a/src/providers/FeedProvider.tsx
+++ b/src/providers/FeedProvider.tsx
@@ -4,6 +4,7 @@ import storage from '@/services/storage.service'
import { TFeedType } from '@/types'
import { Filter } from 'nostr-tools'
import { createContext, useContext, useEffect, useState } from 'react'
+import { useFollowList } from './FollowListProvider'
import { useNostr } from './NostrProvider'
import { useRelaySets } from './RelaySetsProvider'
@@ -31,7 +32,8 @@ export const useFeed = () => {
}
export function FeedProvider({ children }: { children: React.ReactNode }) {
- const { pubkey, getRelayList, getFollowings } = useNostr()
+ const { pubkey, getRelayList } = useNostr()
+ const { getFollowings } = useFollowList()
const { relaySets } = useRelaySets()
const [feedType, setFeedType] = useState(storage.getFeedType())
const [relayUrls, setRelayUrls] = useState([])
diff --git a/src/providers/FollowListProvider.tsx b/src/providers/FollowListProvider.tsx
index c9ab0bb..8625d1d 100644
--- a/src/providers/FollowListProvider.tsx
+++ b/src/providers/FollowListProvider.tsx
@@ -1,6 +1,7 @@
import { createFollowListDraftEvent } from '@/lib/draft-event'
-import { tagNameEquals } from '@/lib/tag'
+import { getFollowingsFromFollowListEvent } from '@/lib/event'
import client from '@/services/client.service'
+import storage from '@/services/storage.service'
import { Event } from 'nostr-tools'
import { createContext, useContext, useEffect, useMemo, useState } from 'react'
import { useNostr } from './NostrProvider'
@@ -9,6 +10,7 @@ type TFollowListContext = {
followListEvent: Event | undefined
followings: string[]
isFetching: boolean
+ getFollowings: (pubkey: string) => Promise
follow: (pubkey: string) => Promise
unfollow: (pubkey: string) => Promise
}
@@ -24,20 +26,13 @@ export const useFollowList = () => {
}
export function FollowListProvider({ children }: { children: React.ReactNode }) {
- const { pubkey: accountPubkey, publish, updateFollowListEvent } = useNostr()
+ const { pubkey: accountPubkey, publish } = useNostr()
const [followListEvent, setFollowListEvent] = useState(undefined)
const [isFetching, setIsFetching] = useState(true)
- const followings = useMemo(() => {
- return Array.from(
- new Set(
- followListEvent?.tags
- .filter(tagNameEquals('p'))
- .map(([, pubkey]) => pubkey)
- .filter(Boolean)
- .reverse() ?? []
- )
- )
- }, [followListEvent])
+ const followings = useMemo(
+ () => (followListEvent ? getFollowingsFromFollowListEvent(followListEvent) : []),
+ [followListEvent]
+ )
useEffect(() => {
if (!accountPubkey) return
@@ -45,14 +40,26 @@ export function FollowListProvider({ children }: { children: React.ReactNode })
const init = async () => {
setIsFetching(true)
setFollowListEvent(undefined)
+ const storedFollowListEvent = storage.getAccountFollowListEvent(accountPubkey)
+ if (storedFollowListEvent) {
+ setFollowListEvent(storedFollowListEvent)
+ }
const event = await client.fetchFollowListEvent(accountPubkey)
- setFollowListEvent(event)
+ if (event) {
+ updateFollowListEvent(event)
+ }
setIsFetching(false)
}
init()
}, [accountPubkey])
+ const updateFollowListEvent = (event: Event) => {
+ const isNew = storage.setAccountFollowListEvent(event)
+ if (!isNew) return
+ setFollowListEvent(event)
+ }
+
const follow = async (pubkey: string) => {
if (isFetching || !accountPubkey) return
@@ -63,7 +70,6 @@ export function FollowListProvider({ children }: { children: React.ReactNode })
const newFollowListEvent = await publish(newFollowListDraftEvent)
client.updateFollowListCache(accountPubkey, newFollowListEvent)
updateFollowListEvent(newFollowListEvent)
- setFollowListEvent(newFollowListEvent)
}
const unfollow = async (pubkey: string) => {
@@ -76,7 +82,14 @@ export function FollowListProvider({ children }: { children: React.ReactNode })
const newFollowListEvent = await publish(newFollowListDraftEvent)
client.updateFollowListCache(accountPubkey, newFollowListEvent)
updateFollowListEvent(newFollowListEvent)
- setFollowListEvent(newFollowListEvent)
+ }
+
+ const getFollowings = async (pubkey: string) => {
+ const followListEvent = storage.getAccountFollowListEvent(pubkey)
+ if (followListEvent) {
+ return getFollowingsFromFollowListEvent(followListEvent)
+ }
+ return await client.fetchFollowings(pubkey)
}
return (
@@ -85,6 +98,7 @@ export function FollowListProvider({ children }: { children: React.ReactNode })
followListEvent,
followings,
isFetching,
+ getFollowings,
follow,
unfollow
}}
diff --git a/src/providers/NostrProvider/index.tsx b/src/providers/NostrProvider/index.tsx
index 24fd656..67bb39c 100644
--- a/src/providers/NostrProvider/index.tsx
+++ b/src/providers/NostrProvider/index.tsx
@@ -1,11 +1,7 @@
import LoginDialog from '@/components/LoginDialog'
import { BIG_RELAY_URLS } from '@/constants'
import { useToast } from '@/hooks'
-import {
- getFollowingsFromFollowListEvent,
- getProfileFromProfileEvent,
- getRelayListFromRelayListEvent
-} from '@/lib/event'
+import { getProfileFromProfileEvent, getRelayListFromRelayListEvent } from '@/lib/event'
import { formatPubkey } from '@/lib/pubkey'
import client from '@/services/client.service'
import storage from '@/services/storage.service'
@@ -15,17 +11,16 @@ import { Event, kinds } from 'nostr-tools'
import * as nip19 from 'nostr-tools/nip19'
import * as nip49 from 'nostr-tools/nip49'
import { createContext, useContext, useEffect, useState } from 'react'
+import { useTranslation } from 'react-i18next'
import { BunkerSigner } from './bunker.signer'
import { Nip07Signer } from './nip-07.signer'
import { NsecSigner } from './nsec.signer'
-import { useTranslation } from 'react-i18next'
type TNostrContext = {
pubkey: string | null
profile: TProfile | null
profileEvent: Event | null
relayList: TRelayList | null
- followings: string[] | null
account: TAccountPointer | null
accounts: TAccountPointer[]
nsec: string | null
@@ -45,8 +40,6 @@ type TNostrContext = {
checkLogin: (cb?: () => T) => Promise
getRelayList: (pubkey: string) => Promise
updateRelayListEvent: (relayListEvent: Event) => void
- getFollowings: (pubkey: string) => Promise
- updateFollowListEvent: (followListEvent: Event) => void
updateProfileEvent: (profileEvent: Event) => void
}
@@ -71,7 +64,6 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
const [profile, setProfile] = useState(null)
const [profileEvent, setProfileEvent] = useState(null)
const [relayList, setRelayList] = useState(null)
- const [followings, setFollowings] = useState(null)
useEffect(() => {
const init = async () => {
@@ -86,7 +78,6 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
setRelayList(null)
- setFollowings(null)
setProfile(null)
setProfileEvent(null)
setNsec(null)
@@ -112,10 +103,6 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
storedRelayListEvent ? getRelayListFromRelayListEvent(storedRelayListEvent) : null
)
}
- const storedFollowListEvent = storage.getAccountFollowListEvent(account.pubkey)
- if (storedFollowListEvent) {
- setFollowings(getFollowingsFromFollowListEvent(storedFollowListEvent))
- }
const storedProfileEvent = storage.getAccountProfileEvent(account.pubkey)
if (storedProfileEvent) {
setProfileEvent(storedProfileEvent)
@@ -132,17 +119,6 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
if (!isNew) return
setRelayList(getRelayListFromRelayListEvent(relayListEvent))
})
- client.fetchFollowListEvent(account.pubkey).then(async (followListEvent) => {
- if (!followListEvent) {
- if (storedFollowListEvent) return
-
- setFollowings([])
- return
- }
- const isNew = storage.setAccountFollowListEvent(followListEvent)
- if (!isNew) return
- setFollowings(getFollowingsFromFollowListEvent(followListEvent))
- })
client.fetchProfileEvent(account.pubkey).then(async (profileEvent) => {
if (!profileEvent) {
if (storedProfileEvent) return
@@ -344,20 +320,6 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
setRelayList(getRelayListFromRelayListEvent(relayListEvent))
}
- const getFollowings = async (pubkey: string) => {
- const followListEvent = storage.getAccountFollowListEvent(pubkey)
- if (followListEvent) {
- return getFollowingsFromFollowListEvent(followListEvent)
- }
- return await client.fetchFollowings(pubkey)
- }
-
- const updateFollowListEvent = (followListEvent: Event) => {
- const isNew = storage.setAccountFollowListEvent(followListEvent)
- if (!isNew) return
- setFollowings(getFollowingsFromFollowListEvent(followListEvent))
- }
-
const updateProfileEvent = (profileEvent: Event) => {
const isNew = storage.setAccountProfileEvent(profileEvent)
if (!isNew) return
@@ -373,7 +335,6 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
profile,
profileEvent,
relayList,
- followings,
account,
accounts: storage
.getAccounts()
@@ -392,8 +353,6 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
signEvent,
getRelayList,
updateRelayListEvent,
- getFollowings,
- updateFollowListEvent,
updateProfileEvent
}}
>
diff --git a/src/services/storage.service.ts b/src/services/storage.service.ts
index 322de21..a168b59 100644
--- a/src/services/storage.service.ts
+++ b/src/services/storage.service.ts
@@ -28,7 +28,7 @@ class StorageService {
private currentAccount: TAccount | null = null
private accountRelayListEventMap: Record = {} // pubkey -> relayListEvent
private accountFollowListEventMap: Record = {} // pubkey -> followListEvent
- private accountProfileEventMap: Record = {} // pubkey -> profileEvent
+ private accountProfileEventMap: Record = {} // pubkey -> profileEvent
constructor() {
if (!StorageService.instance) {