35 lines
2.4 KiB
TypeScript
35 lines
2.4 KiB
TypeScript
"use client"
|
|
import {useEffect,useRef,useState,useSyncExternalStore} from "react"
|
|
import {testTelegramSchema,type TestTelegramBody} from "@mmapp/contracts/alerts"
|
|
import {can} from "@/lib/auth"
|
|
import {telegramPending,subscribeTelegramPending,setTelegramPending} from "@/lib/alerts-telegram-checkpoint"
|
|
import {ApiClientError} from "@/shared/api/http-client"
|
|
import {testAlertsTelegram} from "@/shared/api/alerts"
|
|
|
|
export function useAlertsTelegramPreview(base:string,live:boolean,available:boolean,onBegin:()=>boolean,onEnd:()=>void){
|
|
const source=JSON.stringify([live,base])
|
|
const unknown=useSyncExternalStore(subscribeTelegramPending,()=>telegramPending(source),()=>false)
|
|
const [busy,setBusy]=useState(false),[error,setError]=useState<string|null>(null),[outcome,setOutcome]=useState<string|null>(null)
|
|
const active=useRef(true),lock=useRef(false),controller=useRef<AbortController|null>(null)
|
|
useEffect(()=>{active.current=true;return()=>{active.current=false;controller.current?.abort()}},[source])
|
|
const enabled=live&&available&&can("mm:alerts:write")
|
|
async function test(payload:TestTelegramBody){
|
|
if(!enabled||lock.current||telegramPending(source)||!active.current||!can("mm:alerts:write"))return false
|
|
const parsed=testTelegramSchema.strict().safeParse(payload)
|
|
if(!parsed.success){setError("Проверьте параметры тестового сообщения");return false}
|
|
if(!onBegin())return false
|
|
lock.current=true;controller.current=new AbortController();setBusy(true);setError(null);setOutcome(null);setTelegramPending(source,true)
|
|
const current=()=>active.current&&can("mm:alerts:write")
|
|
try{
|
|
await testAlertsTelegram(base,parsed.data,{signal:controller.current.signal});if(!current())return false
|
|
setTelegramPending(source,false);setOutcome("Telegram API подтвердил приём тестового правила. Проверьте его в чате.");return true
|
|
}catch(e){
|
|
if(e instanceof ApiClientError&&[400,401,403,409,422].includes(e.status)&¤t())setTelegramPending(source,false)
|
|
if(current())setError(e instanceof Error?e.message:"Результат отправки не получен");return false
|
|
}finally{lock.current=false;controller.current=null;if(active.current){setBusy(false);onEnd()}}
|
|
}
|
|
function review(){if(!enabled||busy)return;setTelegramPending(source,false)}
|
|
function clear(){setError(null);setOutcome(null)}
|
|
return {test,busy,error,outcome,unknown,enabled,review,clear}
|
|
}
|