feat: add browser environment support with access token authentication

Enable the web client to run in plain browser environments alongside Telegram Mini App support:

- Server: Add CLI_API_TOKEN authentication path as alternative to Telegram initData
- Client: Add useAuthSource hook to detect and manage Telegram vs browser auth sources
- Client: Add usePlatform hook for platform abstraction with graceful haptic feedback degradation
- Client: Add LoginPrompt component for browser access token login
- Client: Extend useTheme to fall back to system prefers-color-scheme in browser
- Client: Migrate all direct HapticFeedback calls to use usePlatform hook
This commit is contained in:
weishu
2025-12-18 12:45:49 +08:00
parent 5fe1256e11
commit cf2b96b566
14 changed files with 552 additions and 96 deletions
+55
View File
@@ -0,0 +1,55 @@
import { useMemo } from 'react'
import { getTelegramWebApp } from './useTelegram'
export type HapticStyle = 'light' | 'medium' | 'heavy' | 'rigid' | 'soft'
export type HapticNotification = 'error' | 'success' | 'warning'
export type PlatformHaptic = {
/** Trigger impact feedback */
impact: (style: HapticStyle) => void
/** Trigger notification feedback */
notification: (type: HapticNotification) => void
/** Trigger selection changed feedback */
selection: () => void
}
export type Platform = {
/** Whether running in Telegram Mini App */
isTelegram: boolean
/** Haptic feedback (no-op on browser) */
haptic: PlatformHaptic
}
function createHaptic(): PlatformHaptic {
return {
impact: (style: HapticStyle) => {
getTelegramWebApp()?.HapticFeedback?.impactOccurred(style)
},
notification: (type: HapticNotification) => {
getTelegramWebApp()?.HapticFeedback?.notificationOccurred(type)
},
selection: () => {
getTelegramWebApp()?.HapticFeedback?.selectionChanged()
}
}
}
// Singleton haptic instance (functions are stable)
const haptic = createHaptic()
export function usePlatform(): Platform {
const isTelegram = useMemo(() => getTelegramWebApp() !== null, [])
return {
isTelegram,
haptic
}
}
// Non-hook version for use outside React components
export function getPlatform(): Platform {
return {
isTelegram: getTelegramWebApp() !== null,
haptic
}
}