2026-02-04 05:03:06 +03:00
|
|
|
|
// hooks/useTelegramWebApp.ts
|
|
|
|
|
|
// Hook для интеграции с Telegram WebApp API
|
|
|
|
|
|
|
|
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
|
|
|
|
|
|
|
|
export function useTelegramWebApp() {
|
2026-02-08 18:59:02 +03:00
|
|
|
|
const [webApp, setWebApp] = useState<any>(null);
|
2026-02-04 05:03:06 +03:00
|
|
|
|
const [isReady, setIsReady] = useState(false);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
// Проверяем доступность Telegram WebApp только на клиенте
|
|
|
|
|
|
if (typeof window === 'undefined') return;
|
|
|
|
|
|
|
2026-02-09 06:38:35 +03:00
|
|
|
|
const tg = (window as any).Telegram?.WebApp;
|
2026-02-04 05:03:06 +03:00
|
|
|
|
if (!tg) {
|
|
|
|
|
|
console.warn('[TelegramWebApp] Not running in Telegram');
|
|
|
|
|
|
setIsReady(true); // Всё равно помечаем как ready для dev
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('[TelegramWebApp] Initializing...', {
|
|
|
|
|
|
platform: tg.platform,
|
|
|
|
|
|
version: tg.version,
|
|
|
|
|
|
colorScheme: tg.colorScheme,
|
|
|
|
|
|
user: tg.initDataUnsafe.user,
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// Инициализация Telegram WebApp
|
|
|
|
|
|
tg.ready();
|
|
|
|
|
|
tg.expand();
|
|
|
|
|
|
|
|
|
|
|
|
// Настройка темы
|
|
|
|
|
|
tg.setHeaderColor('bg_color');
|
|
|
|
|
|
tg.setBackgroundColor('#18222d');
|
|
|
|
|
|
|
|
|
|
|
|
// Отключить подтверждение закрытия (можно включить при необходимости)
|
|
|
|
|
|
tg.disableClosingConfirmation();
|
|
|
|
|
|
|
|
|
|
|
|
setWebApp(tg);
|
|
|
|
|
|
setIsReady(true);
|
|
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
tg.MainButton.hide();
|
|
|
|
|
|
tg.BackButton.hide();
|
|
|
|
|
|
};
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
webApp,
|
|
|
|
|
|
isReady,
|
|
|
|
|
|
isTelegram: !!webApp,
|
|
|
|
|
|
user: webApp?.initDataUnsafe.user,
|
|
|
|
|
|
platform: webApp?.platform,
|
|
|
|
|
|
colorScheme: webApp?.colorScheme,
|
|
|
|
|
|
themeParams: webApp?.themeParams,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Helper функции для удобства
|
|
|
|
|
|
|
|
|
|
|
|
export function useTelegramMainButton(
|
|
|
|
|
|
text: string,
|
|
|
|
|
|
onClick: () => void,
|
|
|
|
|
|
options?: {
|
|
|
|
|
|
color?: string;
|
|
|
|
|
|
textColor?: string;
|
|
|
|
|
|
enabled?: boolean;
|
|
|
|
|
|
}
|
|
|
|
|
|
) {
|
|
|
|
|
|
const { webApp } = useTelegramWebApp();
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (!webApp) return;
|
|
|
|
|
|
|
|
|
|
|
|
webApp.MainButton.setText(text);
|
|
|
|
|
|
webApp.MainButton.onClick(onClick);
|
|
|
|
|
|
|
|
|
|
|
|
if (options?.color) {
|
|
|
|
|
|
webApp.MainButton.color = options.color;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (options?.textColor) {
|
|
|
|
|
|
webApp.MainButton.textColor = options.textColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (options?.enabled !== undefined) {
|
|
|
|
|
|
if (options.enabled) {
|
|
|
|
|
|
webApp.MainButton.enable();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
webApp.MainButton.disable();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
webApp.MainButton.show();
|
|
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
webApp.MainButton.offClick(onClick);
|
|
|
|
|
|
webApp.MainButton.hide();
|
|
|
|
|
|
};
|
|
|
|
|
|
}, [webApp, text, onClick, options]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useTelegramBackButton(onClick: () => void) {
|
|
|
|
|
|
const { webApp } = useTelegramWebApp();
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (!webApp) return;
|
|
|
|
|
|
|
|
|
|
|
|
webApp.BackButton.onClick(onClick);
|
|
|
|
|
|
webApp.BackButton.show();
|
|
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
webApp.BackButton.offClick(onClick);
|
|
|
|
|
|
webApp.BackButton.hide();
|
|
|
|
|
|
};
|
|
|
|
|
|
}, [webApp, onClick]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useTelegramHaptic() {
|
|
|
|
|
|
const { webApp } = useTelegramWebApp();
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
impact: (style: 'light' | 'medium' | 'heavy' | 'rigid' | 'soft' = 'medium') => {
|
|
|
|
|
|
webApp?.HapticFeedback.impactOccurred(style);
|
|
|
|
|
|
},
|
|
|
|
|
|
notification: (type: 'error' | 'success' | 'warning') => {
|
|
|
|
|
|
webApp?.HapticFeedback.notificationOccurred(type);
|
|
|
|
|
|
},
|
|
|
|
|
|
selection: () => {
|
|
|
|
|
|
webApp?.HapticFeedback.selectionChanged();
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|