refactor: 🏗️

This commit is contained in:
codytseng
2025-01-18 22:46:02 +08:00
parent fa455ba127
commit 34ff0cd314
5 changed files with 40 additions and 65 deletions

View File

@@ -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>

View File

@@ -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[]>([])

View File

@@ -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
}}

View File

@@ -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
}}
>

View File

@@ -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) {