101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import { useState } from 'react'
|
|
import { articlePublisher } from '@/lib/articlePublisher'
|
|
import { nostrService } from '@/lib/nostr'
|
|
import type { ArticleDraft } from '@/lib/articlePublisher'
|
|
import type { RelayPublishStatus } from '@/lib/publishResult'
|
|
import type { PublishedArticle } from '@/lib/articlePublisherTypes'
|
|
|
|
interface UseArticlePublishingState {
|
|
loading: boolean
|
|
error: string | null
|
|
success: boolean
|
|
relayStatuses: RelayPublishStatus[]
|
|
}
|
|
|
|
interface ArticlePublishingApi extends UseArticlePublishingState {
|
|
publishArticle: (draft: ArticleDraft) => Promise<string | null>
|
|
}
|
|
|
|
export function useArticlePublishing(pubkey: string | null): {
|
|
loading: boolean
|
|
error: string | null
|
|
success: boolean
|
|
relayStatuses: RelayPublishStatus[]
|
|
publishArticle: (draft: ArticleDraft) => Promise<string | null>
|
|
} {
|
|
const [loading, setLoading] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
const [success, setSuccess] = useState(false)
|
|
const [relayStatuses, setRelayStatuses] = useState<RelayPublishStatus[]>([])
|
|
|
|
const publishArticle = buildPublishArticleHandler({
|
|
pubkey,
|
|
setLoading,
|
|
setError,
|
|
setSuccess,
|
|
setRelayStatuses,
|
|
})
|
|
|
|
const api: ArticlePublishingApi = { loading, error, success, relayStatuses, publishArticle }
|
|
return api
|
|
}
|
|
|
|
function validateDraft(draft: ArticleDraft): string | null {
|
|
if (!draft.title.trim() || !draft.preview.trim() || !draft.content.trim()) {
|
|
return 'Please fill in all fields'
|
|
}
|
|
return null
|
|
}
|
|
|
|
function buildPublishArticleHandler(params: {
|
|
pubkey: string | null
|
|
setLoading: (loading: boolean) => void
|
|
setError: (error: string | null) => void
|
|
setSuccess: (success: boolean) => void
|
|
setRelayStatuses: (statuses: RelayPublishStatus[]) => void
|
|
}): (draft: ArticleDraft) => Promise<string | null> {
|
|
return async (draft: ArticleDraft): Promise<string | null> => {
|
|
if (!params.pubkey) {
|
|
params.setError('Please connect with Nostr first')
|
|
return null
|
|
}
|
|
|
|
const validationError = validateDraft(draft)
|
|
if (validationError) {
|
|
params.setError(validationError)
|
|
return null
|
|
}
|
|
|
|
params.setLoading(true)
|
|
params.setError(null)
|
|
params.setRelayStatuses([])
|
|
|
|
try {
|
|
const privateKey = nostrService.getPrivateKey()
|
|
const result = await articlePublisher.publishArticle(draft, params.pubkey, privateKey ?? undefined)
|
|
return handlePublishResult({ result, setSuccess: params.setSuccess, setRelayStatuses: params.setRelayStatuses, setError: params.setError })
|
|
} catch (e) {
|
|
params.setError(e instanceof Error ? e.message : 'Failed to publish article')
|
|
return null
|
|
} finally {
|
|
params.setLoading(false)
|
|
}
|
|
}
|
|
}
|
|
|
|
function handlePublishResult(params: {
|
|
result: PublishedArticle
|
|
setSuccess: (success: boolean) => void
|
|
setRelayStatuses: (statuses: RelayPublishStatus[]) => void
|
|
setError: (error: string | null) => void
|
|
}): string | null {
|
|
if (params.result.success) {
|
|
params.setSuccess(true)
|
|
params.setRelayStatuses(params.result.relayStatuses ?? [])
|
|
return params.result.articleId ? params.result.articleId : null
|
|
}
|
|
|
|
params.setError(params.result.error ?? 'Failed to publish article')
|
|
return null
|
|
}
|