feat: add confirmation prompts for creating new follow and mute lists

This commit is contained in:
codytseng 2025-08-13 23:23:10 +08:00
parent 71cf05c820
commit 9c3d9a5432
17 changed files with 101 additions and 16 deletions

View file

@ -2,6 +2,7 @@ import { createFollowListDraftEvent } from '@/lib/draft-event'
import { getPubkeysFromPTags } from '@/lib/tag'
import client from '@/services/client.service'
import { createContext, useContext, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useNostr } from './NostrProvider'
type TFollowListContext = {
@ -21,6 +22,7 @@ export const useFollowList = () => {
}
export function FollowListProvider({ children }: { children: React.ReactNode }) {
const { t } = useTranslation()
const { pubkey: accountPubkey, followListEvent, publish, updateFollowListEvent } = useNostr()
const followings = useMemo(
() => (followListEvent ? getPubkeysFromPTags(followListEvent.tags) : []),
@ -31,6 +33,13 @@ export function FollowListProvider({ children }: { children: React.ReactNode })
if (!accountPubkey) return
const followListEvent = await client.fetchFollowListEvent(accountPubkey)
if (!followListEvent) {
const result = confirm(t('FollowListNotFoundConfirmation'))
if (!result) {
return
}
}
const newFollowListDraftEvent = createFollowListDraftEvent(
(followListEvent?.tags ?? []).concat([['p', pubkey]]),
followListEvent?.content

View file

@ -5,10 +5,10 @@ import indexedDb from '@/services/indexed-db.service'
import dayjs from 'dayjs'
import { Event } from 'nostr-tools'
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { z } from 'zod'
import { useNostr } from './NostrProvider'
import { useTranslation } from 'react-i18next'
type TMuteListContext = {
mutePubkeys: string[]
@ -116,12 +116,23 @@ export function MuteListProvider({ children }: { children: React.ReactNode }) {
return event
}
const checkMuteListEvent = (muteListEvent: Event | null) => {
if (!muteListEvent) {
const result = confirm(t('MuteListNotFoundConfirmation'))
if (!result) {
throw new Error('Mute list not found')
}
}
}
const mutePubkeyPublicly = async (pubkey: string) => {
if (!accountPubkey || changing) return
setChanging(true)
try {
const muteListEvent = await client.fetchMuteListEvent(accountPubkey)
checkMuteListEvent(muteListEvent)
if (
muteListEvent &&
muteListEvent.tags.some(([tagName, tagValue]) => tagName === 'p' && tagValue === pubkey)
@ -132,6 +143,8 @@ export function MuteListProvider({ children }: { children: React.ReactNode }) {
const newMuteListEvent = await publishNewMuteListEvent(newTags, muteListEvent?.content)
const privateTags = await getPrivateTags(newMuteListEvent)
await updateMuteListEvent(newMuteListEvent, privateTags)
} catch (error) {
toast.error(t('Failed to mute user publicly') + ': ' + (error as Error).message)
} finally {
setChanging(false)
}
@ -143,6 +156,7 @@ export function MuteListProvider({ children }: { children: React.ReactNode }) {
setChanging(true)
try {
const muteListEvent = await client.fetchMuteListEvent(accountPubkey)
checkMuteListEvent(muteListEvent)
const privateTags = muteListEvent ? await getPrivateTags(muteListEvent) : []
if (privateTags.some(([tagName, tagValue]) => tagName === 'p' && tagValue === pubkey)) {
return
@ -152,6 +166,8 @@ export function MuteListProvider({ children }: { children: React.ReactNode }) {
const cipherText = await nip04Encrypt(accountPubkey, JSON.stringify(newPrivateTags))
const newMuteListEvent = await publishNewMuteListEvent(muteListEvent?.tags ?? [], cipherText)
await updateMuteListEvent(newMuteListEvent, newPrivateTags)
} catch (error) {
toast.error(t('Failed to mute user privately') + ': ' + (error as Error).message)
} finally {
setChanging(false)
}