Files
LTX-DeskWEB/frontend/hooks/use-hf-auth.ts
T

95 lines
2.8 KiB
TypeScript

import { useState, useEffect, useCallback } from 'react'
import { ApiClient, type ApiSuccessOf } from '../lib/api-client'
import { logger } from '../lib/logger'
type HfAuthStatus = ApiSuccessOf<'getHuggingFaceAuthStatus'>['status']
interface UseHfAuthResult {
hfAuthStatus: HfAuthStatus
hfAuthPolling: boolean
startHuggingFaceLogin: () => Promise<void>
handleHuggingFaceLogout: () => Promise<void>
}
const NOOP = async () => {}
export function useHfAuth(enabled: boolean): UseHfAuthResult {
// Used for gated downloads (LTX 2.5 base models, catalog LoRAs / IC-LoRAs).
const [hfAuthStatus, setHfAuthStatus] = useState<HfAuthStatus>('not_authenticated')
const [hfAuthPolling, setHfAuthPolling] = useState(false)
// One-time check when enabled becomes true
useEffect(() => {
if (!enabled) return
const checkAuth = async () => {
const result = await ApiClient.getHuggingFaceAuthStatus()
if (!result.ok) {
logger.error(`HF auth status check failed: ${result.error.message}`)
return
}
setHfAuthStatus(result.data.status)
}
void checkAuth()
}, [enabled])
// Poll while waiting for user to complete auth in browser
useEffect(() => {
if (!hfAuthPolling) return
const interval = setInterval(async () => {
const result = await ApiClient.getHuggingFaceAuthStatus()
if (!result.ok) {
logger.error(`HF auth status check failed: ${result.error.message}`)
return
}
const { status } = result.data
setHfAuthStatus(status)
if (status === 'authenticated') setHfAuthPolling(false)
}, 2000)
return () => clearInterval(interval)
}, [hfAuthPolling])
const startHuggingFaceLogin = useCallback(async () => {
const result = await ApiClient.startHuggingFaceLogin()
if (!result.ok) {
logger.error(`HF login failed: ${result.error.message}`)
return
}
const params = result.data
setHfAuthPolling(true)
await window.electronAPI.openHuggingFaceAuth({
clientId: params.client_id,
redirectUri: params.redirect_uri,
scope: params.scope,
state: params.state,
codeChallenge: params.code_challenge,
codeChallengeMethod: params.code_challenge_method,
})
}, [])
const handleHuggingFaceLogout = useCallback(async () => {
const result = await ApiClient.huggingFaceLogout()
if (!result.ok) {
logger.error(`HF logout failed: ${result.error.message}`)
return
}
setHfAuthStatus('not_authenticated')
}, [])
if (!enabled) {
return {
hfAuthStatus: 'authenticated',
hfAuthPolling: false,
startHuggingFaceLogin: NOOP,
handleHuggingFaceLogout: NOOP,
}
}
return {
hfAuthStatus,
hfAuthPolling,
startHuggingFaceLogin,
handleHuggingFaceLogout,
}
}