157 lines
5.0 KiB
TypeScript
157 lines
5.0 KiB
TypeScript
import { useState } from 'react'
|
|
import { nostrService } from '@/lib/nostr'
|
|
import { articlePublisher } from '@/lib/articlePublisher'
|
|
import type { Article } from '@/types/nostr'
|
|
import type { NostrProfile } from '@/types/nostr'
|
|
|
|
interface AuthorPresentationDraft {
|
|
authorName: string
|
|
presentation: string
|
|
contentDescription: string
|
|
mainnetAddress: string
|
|
pictureUrl?: string
|
|
}
|
|
|
|
type UseAuthorPresentationResult = {
|
|
loading: boolean
|
|
error: string | null
|
|
success: boolean
|
|
publishPresentation: (draft: AuthorPresentationDraft) => Promise<void>
|
|
checkPresentationExists: () => Promise<Article | null>
|
|
deletePresentation: (articleId: string) => Promise<void>
|
|
}
|
|
|
|
export function useAuthorPresentation(pubkey: string | null): UseAuthorPresentationResult {
|
|
const [loading, setLoading] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
const [success, setSuccess] = useState(false)
|
|
|
|
const publishPresentation = (draft: AuthorPresentationDraft): Promise<void> =>
|
|
publishAuthorPresentation({ pubkey, draft, setLoading, setError, setSuccess })
|
|
|
|
const checkPresentationExists = (): Promise<Article | null> => checkPresentation({ pubkey })
|
|
|
|
const deletePresentation = (articleId: string): Promise<void> =>
|
|
deleteAuthorPresentation({ pubkey, articleId, setLoading, setError })
|
|
|
|
return {
|
|
loading,
|
|
error,
|
|
success,
|
|
publishPresentation,
|
|
checkPresentationExists,
|
|
deletePresentation,
|
|
}
|
|
}
|
|
|
|
async function publishAuthorPresentation(params: {
|
|
pubkey: string | null
|
|
draft: AuthorPresentationDraft
|
|
setLoading: (value: boolean) => void
|
|
setError: (value: string | null) => void
|
|
setSuccess: (value: boolean) => void
|
|
}): Promise<void> {
|
|
if (!params.pubkey) {
|
|
params.setError('Clé publique non disponible')
|
|
return
|
|
}
|
|
|
|
params.setLoading(true)
|
|
params.setError(null)
|
|
try {
|
|
const privateKey = getPrivateKeyOrThrow('Clé privée requise pour publier. Veuillez vous connecter avec un portefeuille Nostr qui fournit des capacités de signature.')
|
|
await updateProfileBestEffort(params.draft)
|
|
const { title, preview, fullContent } = buildPresentationContent(params.draft)
|
|
const result = await articlePublisher.publishPresentationArticle(
|
|
{
|
|
title,
|
|
preview,
|
|
content: fullContent,
|
|
presentation: params.draft.presentation,
|
|
contentDescription: params.draft.contentDescription,
|
|
mainnetAddress: params.draft.mainnetAddress,
|
|
...(params.draft.pictureUrl ? { pictureUrl: params.draft.pictureUrl } : {}),
|
|
},
|
|
params.pubkey,
|
|
privateKey
|
|
)
|
|
if (result.success) {
|
|
params.setSuccess(true)
|
|
} else {
|
|
params.setError(result.error ?? 'Erreur lors de la publication')
|
|
}
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : 'Erreur inconnue'
|
|
console.error('Error publishing presentation:', e)
|
|
params.setError(errorMessage)
|
|
} finally {
|
|
params.setLoading(false)
|
|
}
|
|
}
|
|
|
|
async function updateProfileBestEffort(draft: AuthorPresentationDraft): Promise<void> {
|
|
const profileUpdates: Partial<NostrProfile> = {
|
|
name: draft.authorName.trim(),
|
|
...(draft.pictureUrl ? { picture: draft.pictureUrl } : {}),
|
|
}
|
|
try {
|
|
await nostrService.updateProfile(profileUpdates)
|
|
} catch (e) {
|
|
console.error('Error updating profile:', e)
|
|
}
|
|
}
|
|
|
|
function buildPresentationContent(draft: AuthorPresentationDraft): { title: string; preview: string; fullContent: string } {
|
|
const title = `Présentation de ${draft.authorName.trim()}`
|
|
const preview = draft.presentation.substring(0, 200)
|
|
const fullContent = `${draft.presentation}\n\n---\n\nDescription du contenu :\n${draft.contentDescription}`
|
|
return { title, preview, fullContent }
|
|
}
|
|
|
|
async function checkPresentation(params: { pubkey: string | null }): Promise<Article | null> {
|
|
if (!params.pubkey) {
|
|
return null
|
|
}
|
|
try {
|
|
return articlePublisher.getAuthorPresentation(params.pubkey)
|
|
} catch (e) {
|
|
console.error('Error checking presentation:', e)
|
|
return null
|
|
}
|
|
}
|
|
|
|
async function deleteAuthorPresentation(params: {
|
|
pubkey: string | null
|
|
articleId: string
|
|
setLoading: (value: boolean) => void
|
|
setError: (value: string | null) => void
|
|
}): Promise<void> {
|
|
if (!params.pubkey) {
|
|
throw new Error('Clé publique non disponible')
|
|
}
|
|
params.setLoading(true)
|
|
params.setError(null)
|
|
try {
|
|
const privateKey = getPrivateKeyOrThrow(
|
|
'Clé privée requise pour supprimer. Veuillez vous connecter avec un portefeuille Nostr qui fournit des capacités de signature.'
|
|
)
|
|
const { deleteArticleEvent } = await import('@/lib/articleMutations')
|
|
await deleteArticleEvent(params.articleId, params.pubkey, privateKey)
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : 'Erreur inconnue'
|
|
console.error('Error deleting presentation:', e)
|
|
params.setError(errorMessage)
|
|
throw e
|
|
} finally {
|
|
params.setLoading(false)
|
|
}
|
|
}
|
|
|
|
function getPrivateKeyOrThrow(message: string): string {
|
|
const privateKey = nostrService.getPrivateKey()
|
|
if (!privateKey) {
|
|
throw new Error(message)
|
|
}
|
|
return privateKey
|
|
}
|