213 lines
7.0 KiB
TypeScript
213 lines
7.0 KiB
TypeScript
import { configStorage } from '@/lib/configStorage'
|
|
import type { Nip95Config } from '@/lib/configStorageTypes'
|
|
import { t } from '@/lib/i18n'
|
|
import { userConfirm } from '@/lib/userConfirm'
|
|
|
|
export async function loadApis(params: {
|
|
setApis: (value: Nip95Config[]) => void
|
|
setLoading: (value: boolean) => void
|
|
setError: (value: string | null) => void
|
|
}): Promise<void> {
|
|
try {
|
|
params.setLoading(true)
|
|
params.setError(null)
|
|
const config = await configStorage.getConfig()
|
|
params.setApis(config.nip95Apis.sort((a, b) => a.priority - b.priority))
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : t('settings.nip95.error.loadFailed')
|
|
params.setError(errorMessage)
|
|
console.error('[Nip95Config] Error loading APIs:', e)
|
|
} finally {
|
|
params.setLoading(false)
|
|
}
|
|
}
|
|
|
|
export async function toggleEnabled(params: {
|
|
id: string
|
|
enabled: boolean
|
|
setApis: (value: Nip95Config[]) => void
|
|
setError: (value: string | null) => void
|
|
onConfigChange: (() => void) | undefined
|
|
}): Promise<void> {
|
|
try {
|
|
await configStorage.updateNip95Api(params.id, { enabled: params.enabled })
|
|
await reloadApis({ setApis: params.setApis, setError: params.setError })
|
|
params.onConfigChange?.()
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : t('settings.nip95.error.updateFailed')
|
|
params.setError(errorMessage)
|
|
console.error('[Nip95Config] Error updating API:', e)
|
|
}
|
|
}
|
|
|
|
export async function updateUrl(params: {
|
|
id: string
|
|
url: string
|
|
setApis: (value: Nip95Config[]) => void
|
|
setError: (value: string | null) => void
|
|
setEditingId: (value: string | null) => void
|
|
onConfigChange: (() => void) | undefined
|
|
}): Promise<void> {
|
|
try {
|
|
await configStorage.updateNip95Api(params.id, { url: params.url })
|
|
await reloadApis({ setApis: params.setApis, setError: params.setError })
|
|
params.setEditingId(null)
|
|
params.onConfigChange?.()
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : t('settings.nip95.error.urlFailed')
|
|
params.setError(errorMessage)
|
|
console.error('[Nip95Config] Error updating URL:', e)
|
|
}
|
|
}
|
|
|
|
export async function addApi(params: {
|
|
newUrl: string
|
|
setError: (value: string | null) => void
|
|
setNewUrl: (value: string) => void
|
|
setShowAddForm: (value: boolean | ((prev: boolean) => boolean)) => void
|
|
setApis: (value: Nip95Config[]) => void
|
|
onConfigChange: (() => void) | undefined
|
|
}): Promise<void> {
|
|
if (!params.newUrl.trim()) {
|
|
params.setError(t('settings.nip95.error.urlRequired'))
|
|
return
|
|
}
|
|
try {
|
|
void new URL(params.newUrl)
|
|
await configStorage.addNip95Api(params.newUrl.trim(), false)
|
|
params.setNewUrl('')
|
|
params.setShowAddForm(false)
|
|
await reloadApis({ setApis: params.setApis, setError: params.setError })
|
|
params.onConfigChange?.()
|
|
} catch (e) {
|
|
params.setError(getAddApiErrorMessage(e))
|
|
console.error('[Nip95Config] Error adding API:', e)
|
|
}
|
|
}
|
|
|
|
export async function removeApi(params: {
|
|
id: string
|
|
setApis: (value: Nip95Config[]) => void
|
|
setError: (value: string | null) => void
|
|
onConfigChange: (() => void) | undefined
|
|
}): Promise<void> {
|
|
const confirmed = await userConfirm(t('settings.nip95.remove.confirm'))
|
|
if (!confirmed) {
|
|
return
|
|
}
|
|
try {
|
|
await configStorage.removeNip95Api(params.id)
|
|
await reloadApis({ setApis: params.setApis, setError: params.setError })
|
|
params.onConfigChange?.()
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : t('settings.nip95.error.removeFailed')
|
|
params.setError(errorMessage)
|
|
console.error('[Nip95Config] Error removing API:', e)
|
|
}
|
|
}
|
|
|
|
export function onDragStart(params: {
|
|
e: React.DragEvent<HTMLDivElement>
|
|
id: string
|
|
setDraggedId: (value: string | null) => void
|
|
}): void {
|
|
params.setDraggedId(params.id)
|
|
const { dataTransfer } = params.e
|
|
dataTransfer.effectAllowed = 'move'
|
|
dataTransfer.setData('text/plain', params.id)
|
|
}
|
|
|
|
export function onDragOver(params: {
|
|
e: React.DragEvent<HTMLDivElement>
|
|
id: string
|
|
setDragOverId: (value: string | null) => void
|
|
}): void {
|
|
params.e.preventDefault()
|
|
const { dataTransfer } = params.e
|
|
dataTransfer.dropEffect = 'move'
|
|
params.setDragOverId(params.id)
|
|
}
|
|
|
|
export async function onDrop(params: {
|
|
e: React.DragEvent<HTMLDivElement>
|
|
targetId: string
|
|
apis: Nip95Config[]
|
|
draggedId: string | null
|
|
setApis: (value: Nip95Config[]) => void
|
|
setDraggedId: (value: string | null) => void
|
|
setDragOverId: (value: string | null) => void
|
|
setError: (value: string | null) => void
|
|
onConfigChange: (() => void) | undefined
|
|
}): Promise<void> {
|
|
params.e.preventDefault()
|
|
params.setDragOverId(null)
|
|
if (!params.draggedId || params.draggedId === params.targetId) {
|
|
params.setDraggedId(null)
|
|
return
|
|
}
|
|
const reordered = reorderApis({ apis: params.apis, draggedId: params.draggedId, targetId: params.targetId })
|
|
if (!reordered) {
|
|
params.setDraggedId(null)
|
|
return
|
|
}
|
|
params.setApis(reordered)
|
|
params.setDraggedId(null)
|
|
await updatePriorities({ apis: reordered, setError: params.setError, onConfigChange: params.onConfigChange })
|
|
}
|
|
|
|
async function reloadApis(params: { setApis: (value: Nip95Config[]) => void; setError: (value: string | null) => void }): Promise<void> {
|
|
try {
|
|
const config = await configStorage.getConfig()
|
|
params.setApis(config.nip95Apis.sort((a, b) => a.priority - b.priority))
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : t('settings.nip95.error.loadFailed')
|
|
params.setError(errorMessage)
|
|
console.error('[Nip95Config] Error reloading APIs:', e)
|
|
}
|
|
}
|
|
|
|
function getAddApiErrorMessage(error: unknown): string {
|
|
if (error instanceof TypeError && error.message.includes('Invalid URL')) {
|
|
return t('settings.nip95.error.invalidUrl')
|
|
}
|
|
if (error instanceof Error) {
|
|
return error.message
|
|
}
|
|
return t('settings.nip95.error.addFailed')
|
|
}
|
|
|
|
function reorderApis(params: { apis: Nip95Config[]; draggedId: string; targetId: string }): Nip95Config[] | null {
|
|
const draggedIndex = params.apis.findIndex((api) => api.id === params.draggedId)
|
|
const targetIndex = params.apis.findIndex((api) => api.id === params.targetId)
|
|
if (draggedIndex === -1 || targetIndex === -1) {
|
|
return null
|
|
}
|
|
const next = [...params.apis]
|
|
const removed = next[draggedIndex]
|
|
if (!removed) {
|
|
return null
|
|
}
|
|
next.splice(draggedIndex, 1)
|
|
next.splice(targetIndex, 0, removed)
|
|
return next
|
|
}
|
|
|
|
async function updatePriorities(params: {
|
|
apis: Nip95Config[]
|
|
setError: (value: string | null) => void
|
|
onConfigChange: (() => void) | undefined
|
|
}): Promise<void> {
|
|
try {
|
|
const updates = params.apis.map((api, index) => {
|
|
const priority = index + 1
|
|
return api.priority !== priority ? configStorage.updateNip95Api(api.id, { priority }) : Promise.resolve()
|
|
})
|
|
await Promise.all(updates)
|
|
params.onConfigChange?.()
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : t('settings.nip95.error.priorityFailed')
|
|
params.setError(errorMessage)
|
|
console.error('[Nip95Config] Error updating priorities:', e)
|
|
}
|
|
}
|