refactor: 🏗️
This commit is contained in:
@@ -17,14 +17,14 @@ export default function App(): JSX.Element {
|
||||
<ScreenSizeProvider>
|
||||
<NostrProvider>
|
||||
<RelaySetsProvider>
|
||||
<FeedProvider>
|
||||
<FollowListProvider>
|
||||
<FollowListProvider>
|
||||
<FeedProvider>
|
||||
<NoteStatsProvider>
|
||||
<PageManager />
|
||||
<Toaster />
|
||||
</NoteStatsProvider>
|
||||
</FollowListProvider>
|
||||
</FeedProvider>
|
||||
</FeedProvider>
|
||||
</FollowListProvider>
|
||||
</RelaySetsProvider>
|
||||
</NostrProvider>
|
||||
</ScreenSizeProvider>
|
||||
|
||||
@@ -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<TFeedType>(storage.getFeedType())
|
||||
const [relayUrls, setRelayUrls] = useState<string[]>([])
|
||||
|
||||
@@ -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<string[]>
|
||||
follow: (pubkey: string) => Promise<void>
|
||||
unfollow: (pubkey: string) => Promise<void>
|
||||
}
|
||||
@@ -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<Event | undefined>(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
|
||||
}}
|
||||
|
||||
@@ -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: <T>(cb?: () => T) => Promise<T | void>
|
||||
getRelayList: (pubkey: string) => Promise<TRelayList>
|
||||
updateRelayListEvent: (relayListEvent: Event) => void
|
||||
getFollowings: (pubkey: string) => Promise<string[]>
|
||||
updateFollowListEvent: (followListEvent: Event) => void
|
||||
updateProfileEvent: (profileEvent: Event) => void
|
||||
}
|
||||
|
||||
@@ -71,7 +64,6 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
|
||||
const [profile, setProfile] = useState<TProfile | null>(null)
|
||||
const [profileEvent, setProfileEvent] = useState<Event | null>(null)
|
||||
const [relayList, setRelayList] = useState<TRelayList | null>(null)
|
||||
const [followings, setFollowings] = useState<string[] | null>(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
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -28,7 +28,7 @@ class StorageService {
|
||||
private currentAccount: TAccount | null = null
|
||||
private accountRelayListEventMap: Record<string, Event | undefined> = {} // pubkey -> relayListEvent
|
||||
private accountFollowListEventMap: Record<string, Event | undefined> = {} // pubkey -> followListEvent
|
||||
private accountProfileEventMap: Record<string, Event> = {} // pubkey -> profileEvent
|
||||
private accountProfileEventMap: Record<string, Event | undefined> = {} // pubkey -> profileEvent
|
||||
|
||||
constructor() {
|
||||
if (!StorageService.instance) {
|
||||
|
||||
Reference in New Issue
Block a user