-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseTelegramWebApp.ts
More file actions
111 lines (90 loc) · 3.5 KB
/
useTelegramWebApp.ts
File metadata and controls
111 lines (90 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { useCallback } from 'react';
import { useToast } from './useToast';
export const useTelegramWebApp = () => {
const { addToast } = useToast();
const initWebApp = useCallback(() => {
try {
const tg = window.Telegram?.WebApp;
if (!tg) {
console.warn('Telegram WebApp is not available');
return;
}
// Initialize WebApp
tg.ready();
tg.expand();
// Set theme colors
tg.setHeaderColor('#000000');
tg.setBackgroundColor('#000000');
// Handle viewport and safe areas
const root = document.documentElement;
const updateSafeAreas = () => {
const safeAreaTop = tg.viewportStableHeight < window.innerHeight
? window.innerHeight - tg.viewportStableHeight
: 0;
root.style.setProperty('--safe-area-top', `${safeAreaTop}px`);
root.style.setProperty('--safe-area-bottom', '0px');
root.style.setProperty('--viewport-height', `${tg.viewportStableHeight}px`);
};
// Initial update
updateSafeAreas();
// Listen for viewport changes
tg.onEvent('viewportChanged', updateSafeAreas);
// Disable native scrolling
document.body.style.height = '100%';
document.body.style.position = 'fixed';
document.body.style.width = '100%';
document.body.style.overflow = 'hidden';
// Handle custom scrolling
let touchStartY = 0;
let activeScrollElement: Element | null = null;
const findScrollableParent = (element: Element | null): Element | null => {
while (element && element !== document.body) {
const style = window.getComputedStyle(element);
if (style.overflowY === 'auto' || style.overflowY === 'scroll') {
return element;
}
element = element.parentElement;
}
return document.querySelector('.scroll-container');
};
const handleTouchStart = (e: TouchEvent) => {
const target = e.target as Element;
activeScrollElement = findScrollableParent(target);
if (activeScrollElement) {
touchStartY = e.touches[0].clientY;
}
};
const handleTouchMove = (e: TouchEvent) => {
if (!activeScrollElement) return;
const touch = e.touches[0];
const deltaY = touchStartY - touch.clientY;
const { scrollTop, scrollHeight, clientHeight } = activeScrollElement;
if (scrollTop <= 0 && deltaY < 0) {
e.preventDefault();
return;
}
if (scrollTop + clientHeight >= scrollHeight && deltaY > 0) {
e.preventDefault();
return;
}
};
const handleTouchEnd = () => {
touchStartY = 0;
activeScrollElement = null;
};
document.addEventListener('touchstart', handleTouchStart, { passive: true });
document.addEventListener('touchmove', handleTouchMove, { passive: false });
document.addEventListener('touchend', handleTouchEnd, { passive: true });
return () => {
document.removeEventListener('touchstart', handleTouchStart);
document.removeEventListener('touchmove', handleTouchMove);
document.removeEventListener('touchend', handleTouchEnd);
tg.offEvent('viewportChanged', updateSafeAreas);
};
} catch (error) {
console.error('Error initializing Telegram WebApp:', error);
addToast('Ошибка инициализации приложения', 'error');
}
}, [addToast]);
return { initWebApp };
};